我有一个常规的Room-> DAO-> Livedata-> Repositiry-> ViewModel-> RecyclerView应用程序。 UI的不同按钮必须将不同的数据列表传递给RecyclerView。
通过按钮单击我想要的:
The Dao @Query:
@Query("SELECT * FROM entry_table WHERE path LIKE :path ORDER BY priority DESC")
LiveData<List<Entry>> getNotesOfFolder(String path); //Returns LiveData with List of Entries
通过Observer的onChanged更新recyclerView,如下所示:
public class RecyclerViewActivity extends AppCompatActivity {…
Observer<List<Entry>> entryObserver = new Observer<List<Entry>>() {
@Override
public void onChanged(List<Entry> entries) {
recyclerAdapter.setEntries(entries);
}
};
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.EntryHolder> {…
public void setEntries(List<Entry> entries) {
this.entries = entries; //setting LiveData content to adapter's List (i.e. entries)
notifyDataSetChanged();
问题是LiveData从DAO接收新值时,我的观察者未调用onChange方法。我相信是因为此LiveData的内容不是被其他LiveData更改而是替换。
我试图再次为Observer重新订阅LiveData,但它有些起作用,但是当我尝试调用一些常规的Room查询(例如@Delete)时,我遇到了多个(最多10个!)onChange调用,其中一些行为很奇怪并将错误的列表传递给RVadapter。
所以有两个问题:
答案 0 :(得分:1)
1)
在viewModel
中,为实时数据创建一个getter方法:
//...
private LiveData<List<Entry>> liveData;
//...
public LiveData<List<Entry>> getLiveData() {
return liveData;
}
在Activity
中:
@Override
protected void onCreate(Bundle savedInstanceState) {
//...
viewModel.getLiveData().observe(this, new Observer<List<Entry>>() {
@Override
public void onChanged(List<Entry> entryList) {
//set new value here
}
});
}
2)DiffUtil
对在回收站视图中更新列表非常有帮助,并且为您提供了一些精美的动画。
答案 1 :(得分:0)
我试图再次为Observer重新订阅LiveData,但它有些起作用,但是当我尝试调用一些常规的Room查询(如@Delete)时,我遇到了多个(最多10个!)onChange调用,其中一些行为异常并将错误的列表传递给RVadapter。
如果您没有先从 old LiveData对象中退订您的观察者...这将是有道理的...在查询更改时替换您的观察者。
如果查询更新,则需要从DAO获取新的LiveData。如果用新的旧LiveData覆盖旧的LiveData,则不仅需要将观察者(重新)订阅到新的LiveData,还需要从旧的Observer取消订阅。否则它将继续存在并不断更新观察者。