我使用room
查询并返回LiveData
来在UI上显示元素。问题是实体经常更改大多数属性,这与UI无关,而且由于UI多次刷新,不会带来任何好处。
我想要的是像快速组合@Published
。
这是代码:
@Entity
@Parcelize
data class Foo(@PrimaryKey var code: String,
var p1: Double,
var p2: Int? = null,
var p3: Int? = null,
var p4: Double? = null,
var p5: Int? = null,
var p6: Double? = null,
var p7: Int? = null
): Parcelable
实际上,我只关心code
属性更改insert/delete。
@Query("SELECT * FROM Foo WHERE code IN (:fooIds)")
fun getLiveDataListBy(fooIds`: List<String?>): LiveData<List<Foo>?>?
我在ViewModel中有这个属性,并在片段中观察它。
var foosLiveData: LiveData<List<Fool>>? = null
viewModel.foosLiveData?.observe(viewLifecycleOwner, {
adapter.foos = it
adapter.notifyDataSetChanged()
})
p1
到p7
的属性一直在变化。由于列表一直在刷新。
现在,我可以通过检查来改进它
if (adapter.foos != it) {
adapter.foos = it
adapter.notifyDataSetChanged()
}
但这几乎没有改善。
那么如果可以通过以下方式改进:(我还没有测试(
adapter.foos = it
adapter.notifyDataSetChanged()
}
这可能是有效的,但它会不断检查map
,只可能取出adapter.foos.map { a -> a.code }
来保存一点。
这可能是另一种变通方法。
我还想去掉code
,使用一个新的变量var codeObserver: MutableLiveData(List<String>) = MutableLiveData()
然后
viewModel.foosLiveData?.observe(viewLifecycleOwner, {
viewModel.codeObserver.value = it.foo.map { it.code}
})
viewModel.codeObserver.observe(viewLifecycleOwner, {
adapter.foos = viewModel.foosLiveData?.value
adapter.notifyDataSetChanged()
}
好吧,我还没有测试上面的代码,但看起来方向不对。
那么,有什么更好或正确的方法可以实现只观察一个或几个属性?
使用AsyncListDiffer可以避免重新加载回收器视图适配器。有关更多信息,请参阅谷歌文档。简单地说,它可以使用列表的LiveData中的值,并简单地为适配器显示数据。当接收到新的列表时,它通过后台线程上的DiffUtil计算列表内容的差异。