分页库:如何按需重新加载部分数据?
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()。
【讨论】:
以上是关于分页库:如何按需重新加载部分数据?的主要内容,如果未能解决你的问题,请参考以下文章