Flo*_*her 11 paging android android-paging android-paging-library android-paging-3
我将 Paging 3 与 RemoteMediator 结合使用,它在从网络获取新数据的同时显示缓存的数据。当我刷新我的PagingDataAdapter
(通过调用refresh()
它)时,我希望我的 RecyclerView 在刷新完成后滚动到顶部。在代码实验室loadStateFlow
中,他们尝试通过以下方式处理这个问题:
lifecycleScope.launch {
adapter.loadStateFlow
// Only emit when REFRESH LoadState for RemoteMediator changes.
.distinctUntilChangedBy { it.refresh }
// Only react to cases where Remote REFRESH completes i.e., NotLoading.
.filter { it.refresh is LoadState.NotLoading }
.collect { binding.list.scrollToPosition(0) }
}
Run Code Online (Sandbox Code Playgroud)
这确实会向上滚动,但在 DiffUtil 完成之前。这意味着如果顶部确实插入了新数据,RecyclerView将不会一直向上滚动。
我知道 RecyclerView 适配器有一个AdapterDataObserver
回调,当 DiffUtil 完成比较时我们可以收到通知。但这会导致适配器的各种竞争条件和PREPEND
加载APPEND
状态,这也会导致 DiffUtil 运行(但这里我们不想滚动到顶部)。
一种可行的解决方案是传递PagingData.empty()
到PagingDataAdapter
并重新运行相同的查询(仅调用refresh
是行不通的,因为PagingData
现在是空的并且没有任何内容可以刷新),但我更愿意保持旧数据可见,直到我知道刷新实际上成功了。
看一下代码,加载类型刷新的条件。
repoDatabase.withTransaction {
// clear all tables in the database
if (loadType == LoadType.REFRESH) {
repoDatabase.remoteKeysDao().clearRemoteKeys()
repoDatabase.reposDao().clearRepos()
}
val prevKey = if (page == GITHUB_STARTING_PAGE_INDEX) null else page - 1
val nextKey = if (endOfPaginationReached) null else page + 1
val keys = repos.map {
Log.e("RemoteKeys", "repoId: ${it.id} prevKey: $prevKey nextKey: $nextKey")
RemoteKeys(repoId = it.id, prevKey = prevKey, nextKey = nextKey)
}
repoDatabase.remoteKeysDao().insertAll(keys)
repoDatabase.reposDao().insertAll(repos)
}
Run Code Online (Sandbox Code Playgroud)
如果LoadType 是刷新清除所有表,则应删除该条件。
if (loadType == LoadType.REFRESH) {
repoDatabase.remoteKeysDao().clearRemoteKeys()
repoDatabase.reposDao().clearRepos()
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8549 次 |
最近记录: |