Sar*_*lla 11 android list android-livedata android-architecture-components android-paging
我一直在使用RecyclerView实现新的Paging Library,其中应用程序构建在Architecture Components之上.
填充列表的数据来自Room数据库.实际上,它是从网络中获取的,存储在本地数据库中并提供给列表.
为了提供构建列表所需的数据,我实现了自己的自定义PageKeyedDataSource.一切都按预期工作,除了一个小细节.显示列表后,如果列表行元素的数据发生任何更改,则不会自动更新.因此,例如,如果我的列表显示了具有字段名称的项目列表,并且突然,该字段在本地Room数据库中针对特定行项目更新,则列表不会自动更新行UI.
仅当使用自定义DataSource时才会发生此行为,这与通过直接返回DataSource Factory从DAO自动获取DataSource不同.但是,我需要实现自定义DataSource.
我知道可以通过调用DataSource上的invalidate()方法来重新更新列表来更新它.但是,如果应用程序一次显示2个列表(例如每个半屏),并且此项目出现在两个列表中,则需要分别为两个列表调用invalidate().
我想过一个解决方案,其中,不是使用item的类的实例来填充每个ViewHolder,而是使用它的LiveData包装版本,使每行观察其自己项目的更改并在必要时更新该行UI .不过,我看到这种方法有一些缺点:
我根本不知道,即使考虑到这些缺点,它看起来似乎是一种体面的方法,或者,如果你们中的任何人知道任何其他更清洁和更好的方法来管理它.
先感谢您.
自从上次检查这个问题以来已经有一段时间了,但对于任何感兴趣的人来说,这是我的问题的原因+我为从ViewHolder正确观察LiveData而制作的库(以避免必须使用问题中解释的解决方法)。
我的具体问题是由于 Kotlin 的Data Classes使用不当造成的。使用它们时,需要注意的是(如文档中所述), toString ()、equals()、hashCode()和copy()将仅考虑类构造函数中声明的所有这些属性,而忽略那些在类的主体中声明的。一个简单的例子:
data class MyClass1(val prop: Int, val name: String) {}
data class MyClass2(val prop: Int) {
var name: String = ""
}
fun main() {
val a = MyClass1(1, "a")
val b = MyClass1(1, "b")
println(a == b) //False :) -> a.name != b.name
val c = MyClass2(2)
c.name = "c"
val d = MyClass2(2)
d.name = "d"
println(c == d) //True!! :O -> But c.name != d.name
}
Run Code Online (Sandbox Code Playgroud)
这在实现PagedListAdapter的DiffCallback时特别重要,就好像我们处于示例的MyClass2场景中一样,无论我们更新Room数据库中的name字段多少次,因为DiffCallback的areContentsTheSame()方法可能始终是将返回true,使列表永远不会因该更改而更新。
如果上述原因不是您问题的原因,或者您只是希望能够从ViewHolder正确观察LiveData实例,我开发了一个小型库,它为任何ViewHolder提供生命周期,使其能够观察LiveData实例正确的方法(而不是必须使用问题中解释的解决方法)。
https://github.com/Sarquella/LifecycleCells
| 归档时间: |
|
| 查看次数: |
886 次 |
| 最近记录: |