【问题标题】:Updating a RecyclerView by a new LiveData<List> return from Room dynamically通过从 Room 动态返回的新 LiveData<List> 更新 RecyclerView
【发布时间】:2019-11-06 12:41:19
【问题描述】:

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

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

道@查询:

@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 接收到新值时,我的 Observer 没有调用 onChange 方法。我相信这是因为这个 LiveData 的内容没有被改变,而是被另一个 LiveData 替换。

我尝试再次将 Observer 重新订阅到 LiveData 并且它有点工作,但是当我尝试调用一些常规的 Room 查询(如 @Delete)时,我收到了多个(最多 10 个!)onChange 调用,其中一些行为怪异并将错误的列表传递给 RVadapter。

所以有两个问题:

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

【问题讨论】:

  • 我希望您建议在您的页面中设置refresh 功能。例如,将 SwipeRefreshLayout 添加到您的布局中。我认为这可能有助于获取更新的数据。

标签: android android-recyclerview android-room android-livedata


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

【讨论】:

  • 您刚刚描述了使用 LiveData 的最简单情况。这一切我都已经知道了。这不是我要问的。问题是在我再次订阅 LiveData 之前,观察者不会触发 LiveData 的新值。
【解决方案2】:

我尝试再次将 Observer 重新订阅到 LiveData 并且它有点工作,但是当我尝试调用一些常规的 Room 查询(如 @Delete)时,我收到了多个(最多 10 个!)onChange 调用,其中一些行为怪异并将错误的列表传递给 RVadapter。

如果您没有首先从 old LiveData 对象中取消订阅您的观察者,这将是有意义的......当您的查询更改时您将替换该对象。

如果您的查询更新,您将需要从 DAO 获取新的 LiveData。如果你用新的 LiveData 覆盖旧的 LiveData,你不仅需要(重新)订阅你的 Observer 到新的,你还需要从旧的取消订阅它。否则它将继续存在并不断更新观察者。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-17
    • 1970-01-01
    • 2018-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多