使用自定义DataSource的分页库不会更新Room更新中的行

Sar*_*lla 11 android list android-livedata android-architecture-components android-paging

我一直在使用RecyclerView实现新的Paging Library,其中应用程序构建在Architecture Components之上.

填充列表的数据来自Room数据库.实际上,它是从网络中获取的,存储在本地数据库中并提供给列表.

为了提供构建列表所需的数据,我实现了自己的自定义PageKeyedDataSource.一切都按预期工作,除了一个小细节.显示列表后,如果列表行元素的数据发生任何更改,则不会自动更新.因此,例如,如果我的列表显示了具有字段名称的项目列表,并且突然,该字段在本地Room数据库中针对特定行项目更新,则列表不会自动更新行UI.

仅当使用自定义DataSource时才会发生此行为,这与通过直接返回DataSource FactoryDAO自动获取DataSource不同.但是,我需要实现自定义DataSource.

我知道可以通过调用DataSource上的invalidate()方法来重新更新列表来更新它.但是,如果应用程序一次显示2个列表(例如每个半屏),并且此项目出现在两个列表中,则需要分别为两个列表调用invalidate().

我想过一个解决方案,其中,不是使用item的类的实例来填充每个ViewHolder,而是使用它的LiveData包装版本,使每行观察其自己项目的更改并在必要时更新该行UI .不过,我看到这种方法有一些缺点:

  1. 必须将LifeCycleOwner(例如包含RecyclerView的Fragment)传递给PagedListAdapter,然后将其转发到ViewHolder以观察LiveData包装的项目.
  2. 将为每个列表的新行注册一个新的观察者,所以我根本不知道它是否有过多的计算和内存成本,考虑到它将在应用程序中的每个列表中完成,其中包含很多列表.
  3. 例如,观察LiveData包装项的LifeCycleOwner将是包含RecyclerView的Fragment,而不是ViewHolder本身,每当对该项发生更改时,即使包含该项的行不均匀,也会通知观察者.在那一刻可见,因为列表已滚动,这在我看来像浪费资源,可能会不必要地增加计算成本.

我根本不知道,即使考虑到这些缺点,它看起来似乎是一种体面的方法,或者,如果你们中的任何人知道任何其他更清洁和更好的方法来管理它.

先感谢您.

Sar*_*lla 2

自从上次检查这个问题以来已经有一段时间了,但对于任何感兴趣的人来说,这是我的问题的原因+我为从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)

这在实现PagedListAdapterDiffCallback时特别重要,就好像我们处于示例的MyClass2场景中一样,无论我们更新Room数据库中的name字段多少次,因为DiffCallbackareContentsTheSame()方法可能始终是将返回true,使列表永远不会因该更改而更新。


如果上述原因不是您问题的原因,或者您只是希望能够从ViewHolder正确观察LiveData实例,我开发了一个小型库,它为任何ViewHolder提供生命周期,使其能够观察LiveData实例正确的方法(而不是必须使用问题中解释的解决方法)。

https://github.com/Sarquella/LifecycleCells