分页库:如何按需重新加载部分数据?

Posted

技术标签:

【中文标题】分页库:如何按需重新加载部分数据?【英文标题】:Paging Library: How to reload portion of data on demand? 【发布时间】:2018-04-09 20:40:51 【问题描述】:

我使用Paging Library 对我的数据集进行分页。我要做的是在我的数据库中的数据发生更改后刷新RecyclerView

我有这个LiveData

val listItems: LiveData<PagedList<Snapshot>> = object : LivePagedListProvider<Long, Snapshot>() 
        override fun createDataSource() = SnapshotsDataSource()
    .create(null, PagedList.Config.Builder()
        .setPageSize(PAGE_SIZE)
        .setInitialLoadSizeHint(PAGE_SIZE)
        .setEnablePlaceholders(false)
        .build()
    )

还有DataSource

class SnapshotsDataSource : KeyedDataSource<Long, Snapshot>(), KodeinGlobalAware 

    val db: FirebaseDb = instance()

    override fun getKey(item: Snapshot): Long = item.timestamp

    override fun loadInitial(pageSize: Int): List<Snapshot> 
        val result = db.getSnapshotsTail(pageSize)
        return result
    

    override fun loadAfter(key: Long, pageSize: Int): List<Snapshot> 
        val result = db.getSnapshotsTail(key, pageSize)
        return result.subList(1, result.size)
    

    override fun loadBefore(key: Long, pageSize: Int): List<Snapshot> 
        return emptyList()
    


Adapter 是直截了当的,所以我在此省略。

我尝试在修改数据库时这样做:

fun reload(position) 
    listItems.value!!.loadAround(position)

但它没有帮助。

【问题讨论】:

调用DataSource#invalidate() 方法——虽然它会创建一个新的DataSource... 当我打电话给invalidate() 时,什么也没有发生。它只是在滚动 RecyclerView 时停止进一步的数据加载 如果你调用invalidate,那么应该调用LivePagedListProvider#createDataSource 是的。出于某种原因,它调用了十亿次(无限循环)。看起来像库中的错误。无论如何,尚不清楚无效如何有帮助。当我只需要 1 个或几个项目时,它将使整个列表无效。 不,没有十亿次,invalidate() 只执行一次操作,文档说:"Signal the data source to stop loading, and notify its callback. If invalidate has already been called, this method does nothing." - 我已经使用它并且它工作得很好 - 如果在你的情况下它没有被调用全部,现在它被调用了十亿次,那么您的代码似乎被破坏了 【参考方案1】:

尝试拨打listItems.value!!.datasource.invalidate() 不是直接DataSource#invalidate()

【讨论】:

这不会刷新整个列表吗? (会在瞬间看到一个空白屏幕)【参考方案2】:

我在使用基于 Firestore 的自定义数据源时遇到了同样的问题。加载部分数据而不使所有数据无效并让 UI 刷新/重新加载的唯一方法似乎是通过与 Google 的 Room ORM 库集成。不幸的是,这会缓存我的数据两次,一次是使用 Firestore,另一次是使用 Room,这是不必要的。

请参阅Consider How Content Updates Work 下的文档。实现实时更新的唯一方法是使用 PagedList 实现 Room:如果您直接从 Room 数据库加载数据,更新会自动推送到应用的 UI。

【讨论】:

【参考方案3】:

这是不可能的。您只能使整个列表无效:datasource.invalidate()。

【讨论】:

以上是关于分页库:如何按需重新加载部分数据?的主要内容,如果未能解决你的问题,请参考以下文章

使用分页库显示加载指示器

如何在 Nativescript 中重新启动按需加载?

在分页库 3 中恢复滚动位置

分页库 - 网络 + db 的边界回调,API 获取页面和大小

重新启用按需加载 [NativeScript Vue]

如何在后台重新加载来自网络的新数据