首页 > 解决方案 > 通过新的 LiveData 更新 RecyclerView从 Room 动态返回

问题描述

我有一个常规的 Room->DAO->Livedata->Repositiry->ViewModel->RecyclerView 应用程序。UI 的不同按钮必须将不同的数据列表传递给 RecyclerView。
通过按钮单击我想要:

  1. 在 DAO 中创建新的 @Query 并获得新的 LiveData<`List> 对象作为回报。
  2. 将这些新数据放入 RecyclerViewAdapter 并调用 notifyDataSetChanged() 以制作新的 List 视觉效果。

道@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

recyclerView 通过 Observer 的 onChanged 更新,如下所示:

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 并且它有点工作,但是当我尝试调用一些像 @Delete 这样的常规 Room 查询时,我收到了多个(最多 10 个!)onChange 调用,其中一些行为怪异并通过RVadapter 的错误列表。

所以有两个问题:

  1. 我怎样才能调用我的观察者的 onChanged() ?
  2. 是否有其他一些时尚的方式将新的 LiveData 对象动态传递给 RecyclerView?

标签: androidandroid-recyclerviewandroid-roomandroid-livedata

解决方案


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对在回收站视图中更新您的列表非常有帮助,它为您提供了一些不错的动画。


推荐阅读