DataSource.Invalidate() 后新的 PagedList 只有一页

After DataSource.Invalidate() new PagedList has only one page

我有一个带有分页的列表,它是我使用 Paging 库实现的。可以修改此列表中的项目 (changed/deleted)。 根据官方 documentation,我首先更改我的 DataSource 从中获取页面的内存列表缓存,然后调用 datasource.invalidate() 以创建新对 PagedList/DataSource

If you have more granular update signals, such as a network API signaling an update to a single item in the list, it's recommended to load data from network into memory. Then present that data to the PagedList via a DataSource that wraps an in-memory snapshot. Each time the in-memory copy changes, invalidate the previous DataSource, and a new one wrapping the new state of the snapshot can be created.

如果用户修改第一页上的项目,它会工作并且看起来很好。

但是,如果用户在 datasource.invalidate() 期间在第二页或更远的页面上,他将 在第一页的末尾抛出

调试显示发生这种情况是因为新 PagedList 在提交给 PagedListAdapter.submitList 时只有 第一页 。 Adapter 比较新旧列表并删除所有不在第一页的项目。如果他在第一页上,它总是发生但对用户不可见。

所以对我来说,看起来新对 PagedList/DataSource 不知道获取前一对的页数并且 datasource.invalidate() 不适合文档中的情况。我认为案例可接受的行为然后用户更新所有列表(如滑动刷新)但不是

an update to a single item in the list

有没有人遇到过这样的问题或以某种方式归档了我想要的东西?也许我遗漏了一些技巧,可以帮助我在所有页面上获得新的 PagedList

澄清一下:库版本 2.1.0。基于内存缓存和远程服务的自定义 PageKeyedDataSource(否 Room

使用 observable 方法,您只会获得第一页列表项....如果您想编辑其他项目,您可以通过 adapter.currentlist 方法获得该列表。

示例:

 private fun list():MutableList<String>{
    val list = mutableListOf<String>()
        for (value in videosAdapter.currentList.orEmpty()) {
            val abc = value.snippet.resourceId.videoId
            list.add(abc)
        }
    return list
}

我想分享我的研究,以防有人感兴趣:

  1. 问题 ("lack of feature") 是已知的,至少我在官方跟踪器上找到了几个相关的讨论 one two
  2. 如果您正在使用 PositionalDataSourceItemKeyedDataSource,您应该从 this answer 所说的初始参数深入研究 requestedStartPosition/requestedInitialKey 的方向。我没有太多时间来构建整个解决方案,但这些参数在失效后初始加载时确实不同

关于我的案例:PageKeyedDataSourceHere 你可以看到,在这种类型的数据源中没有类似于 requestedInitialKey 的参数。尽管如此,我还是找到了一个适合我的解决方案,非常简单,尽管感觉像是一个肮脏的把戏:

loadInitial()invalidate() 内存缓存 returns 之后调用所有已加载的页面而不是第一个页面时。 起初我担心如果 requestedLoadSize 是 5 但结果是 50 项列表会出现问题,但事实证明这只是一个提示,可以忽略。只是不要忘记传递对应于最后一个缓存页面而不是第一个的 nextPageKey

希望对您有所帮助