自定义DataSource的分页库未更新Room更新

时间:2018-05-16 09:19:59

标签: android list android-livedata android-architecture-components android-paging

我一直在使用Paging Library实施新的RecyclerView,并在Architecture Components之上构建应用。

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

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

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

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

我想过一个解决方案,其中不是使用项目类的实例来填充每个ViewHolder,而是使用LiveData包装的版本来制作每个LifeCycleOwner行观察其自身项目的更改,并在必要时更新该行UI。尽管如此,我认为这种方法存在一些缺点:

  1. 必须将PagedListAdapter(例如包含RecyclerView的片段)传递给{{3}},然后将其转发到ViewHolder以观察LiveData包装的项目。
  2. 将为每个列表的新行注册一个新的观察者,所以我根本不知道它是否有过多的计算和内存成本,考虑到它将对应用程序中的每个列表进行,其中有很多名单。
  3. 由于观察LiveData包装项目的LifeCycleOwner将是,例如,包含RecyclerView的Fragment,而不是ViewHolder本身,每次对该项目发生更改时,即使包含该项目的行,也会通知观察者在那一刻甚至都看不到,因为列表已经滚动,在我看来,这可能浪费资源,不必要地增加计算成本。
  4. 我完全不知道,即使考虑到这些缺点,它看起来似乎是一种体面的方法,或者,如果你们中的任何人知道任何其他更清洁,更好的方法来管理它。

    提前谢谢。

1 个答案:

答案 0 :(得分:0)

自从上次检查该问题以来已经有一段时间了,但是对于任何感兴趣的人,这都是我的问题的原因+我为了使libraryLiveData到{{3}避免使用问题中说明的解决方法。

我的特定问题是由于Kotlin的ViewHolder使用不当所致。使用它们时,请务必注意(如文档中所述), 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
}

这在实现Data Classes DiffCallback 时特别重要,就像我们处于示例的 MyClass2 这样的场景中一样,无论我们执行多少次更新我们PagedListAdapter数据库中的 name 字段,因为 DiffCallback areContentsTheSame()方法可能总是会返回< em> true ,使列表从不更新该更改。


如果上述原因不是问题的原因,或者您只是想能够从 ViewHolder 正确观察 LiveData 实例,我开发了一个该库可为任何 ViewHolder 提供 Lifecycle ,从而使其能够以正确的方式观察 LiveData 实例(而不必使用本教程中介绍的解决方法问题)。

Room