Ed *_*ave 7 android android-recyclerview android-livedata
底线问题
如果我使用MutableLiveData<List<Article>>,当文章的标题/内容更改,添加了新的文章以及删除了文章时,是否有办法正确通知观察者?
似乎只有在LiveData上设置了一个全新的集合时才有可能发出通知,这似乎会导致UI刷新的效率很低。
假设的例子
假设以下...
我的LiveData类看起来像这样:
public class ArticleViewModel extends ViewModel {
private final MutableLiveData<List<Article>> mArticles = new MutableLiveData<>();
}
Run Code Online (Sandbox Code Playgroud)
我想使用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();
}
}
Run Code Online (Sandbox Code Playgroud)
最后,我的应用程序将允许用户添加新文章,删除现有文章并更改现有文章的名称(需要在RecyclerView列表中进行更新)。我该怎么做呢?
添加/删除文章
如果您从基础Collection中添加/删除项目,则LiveData构造似乎不会通知观察者。看来您必须调用LiveData#setValue,也许ArticleViewModel需要一个看起来像这样的方法:
public void deleteArticle(int index) {
final List<Article> articles = mArticles.getValue();
articles.remove(index);
mArticles.setValue(articles);
}
Run Code Online (Sandbox Code Playgroud)
那不是真的很低效吗,因为它会触发RecyclerView.Adapter中的完全刷新,而不是仅仅添加/删除单个行?
更换名字
如果您更改基础集合中项目的内容,则LiveData构造似乎不会通知观察者。因此,如果我想更改现有文章的标题并将其反映在RecyclerView中,则我的ArticleViewModel必须修改对象并使用整个集合调用LiveData#setValue。
再次,这不是真的效率不高吗,因为它会触发RecyclerView.Adapter中的完全刷新吗?
情况1:
当您添加或删除时因此,当您添加或删除列表中的元素时,您不会更改列表项的引用,因此每次修改 liveData 项时,您都必须通过调用 setValue 方法来更新实时数据值(如果您正在更新)主线程上的项目)或发布值(当您更新后台线程上的值时)
问题是效率不高
解决方案 使用 diffutil
情况2:当您通过编辑项目来更新项目属性时。
问题
仅当顶级值发生更改时,LiveData 才会向其观察者发出更改警报。但是,对于复杂对象,这意味着仅当对象引用发生更改时,而不是当对象的某些属性发生更改时。
解决方案
要观察属性的变化,您需要 PropertyAwareMutableLiveData
class PropertyAwareMutableLiveData<T: BaseObservable>: MutableLiveData<T>() {
private val callback = object: Observable.OnPropertyChangedCallback() {
override fun onPropertyChanged(sender: Observable?, propertyId: Int) {
value = value
}
}
override fun setValue(value: T?) {
super.setValue(value)
value?.addOnPropertyChangedCallback(callback)
}
}
Run Code Online (Sandbox Code Playgroud)
这里需要注意两点:
1.首先,我们的值是一个实现 BaseObservable 接口的泛型类型。这使我们能够访问 OnPropertyChangedCallback。
2.接下来,每当 BaseObservable 的某些属性发生变化时,我们只需将顶层 value 属性重置为其当前值,从而提醒 LiveData 的观察者某些内容发生了变化。
| 归档时间: |
|
| 查看次数: |
1368 次 |
| 最近记录: |