【发布时间】:2018-11-10 18:25:58
【问题描述】:
底线问题
如果我使用MutableLiveData<List<Article>>,是否有办法在文章的标题/内容发生更改、添加新文章和删除文章时正确通知观察者?
似乎只有在 LiveData 上设置了全新的集合时才可能收到通知,这似乎会导致 UI 刷新效率非常低。
假设示例
假设以下...
我的 LiveData 类看起来像这样:
public class ArticleViewModel extends ViewModel {
private final MutableLiveData<List<Article>> mArticles = new MutableLiveData<>();
}
我想使用 RecyclerView 在列表中显示文章。因此,每当我的 Fragment 观察到 ArticleViewModel 的 LiveData 发生变化时,它都会在我的自定义 RecyclerView.Adapter 类上调用以下方法:
public class ArticleRecyclerViewAdapater extends RecyclerView.Adapter<Article> {
private final ArrayList<Article> mValues = new ArrayList<>();
public void resetValues(Collection<Article> articles) {
mValues.clear();
mValues.addAll(articles);
notifyDataSetChanged();
}
}
最后,我的应用程序将允许用户添加新文章、删除现有文章以及更改现有文章的名称(需要在 RecyclerView 列表中更新)。我怎样才能正确地做到这一点?
添加/删除文章
如果您从基础集合中添加/删除项目,LiveData 构造似乎不会通知观察者。看来您必须调用 LiveData#setValue,也许 ArticleViewModel 需要一个看起来像这样的方法:
public void deleteArticle(int index) {
final List<Article> articles = mArticles.getValue();
articles.remove(index);
mArticles.setValue(articles);
}
这不是真的低效吗,因为它会触发 RecyclerView.Adapter 中的完全刷新,而不是仅仅添加/删除一行?
更改名称
如果您更改基础集合中项目的内容,LiveData 构造似乎不会通知观察者。因此,如果我想更改现有文章的标题并将其反映在 RecyclerView 中,那么我的 ArticleViewModel 将不得不修改对象并使用整个集合调用 LiveData#setValue。
同样,这不是真的低效吗,因为它会触发 RecyclerView.Adapter 中的完全刷新?
【问题讨论】:
-
您可以在 recyclerview 旧数据和来自观察者的新数据上使用 diffutil。这样您就不必清除底层数据集并调用 notifydatasetcahged() 。 Diffutil 将处理适当的通知数据调用。
-
参考这个answer并将其与DiffUtil一起使用
标签: android android-recyclerview android-livedata