我在RemoteMediator中使用分页3,它显示缓存的数据,同时从网络中获取新的数据。当我刷新我的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) }
}
这确实是向上滚动的,但是在完成DiffUtil之前。这意味着,如果实际上在顶部插入了新的数据,RecyclerView就不会一直向上滚动.。
我知道RecyclerView适配器有一个AdapterDataObserver
回调,我们可以在DiffUtil完成扩展时得到通知。但是这将导致适配器的PREPEND
和APPEND
加载状态下的各种争用条件,这也会导致DiffUtil运行(但这里我们不想滚动到顶部)。
一种可行的解决方案是将PagingData.empty()
传递给PagingDataAdapter
并重新运行相同的查询(只调用refresh
将无法工作,因为PagingData
现在是空的,没有什么可刷新的),但我更愿意在知道刷新实际上成功之前保持旧数据可见。
发布于 2021-06-18 17:01:11
在搜索静态内容的情况下,我们可以在false
of DiffUtil.ItemCallback
中返回DiffUtil.ItemCallback
作为解决方案。我也使用它来更改排序属性。
发布于 2021-08-06 16:15:20
@Florian,我可以确认,我们不需要postDelayed
滚动到顶部使用3.1.0-alpha03
版本发布于21/07/2021。此外,我还进一步过滤了loadStateFlow
集合,这样它就不会阻止StateRestorationPolicy.PREVENT_WHEN_EMPTY
基于@Alexandr答案工作。我的解决办法是:
在我编写这篇文章时,Paging3的最新版本是3.1.0-alpha03
,所以导入:
androidx.paging:paging-runtime-ktx:3.1.0-alpha03
然后将适配器的恢复策略设置为:
adapter.stateRestorationPolicy = RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY
如果对上述更改有编译错误,请确保至少使用1.2.0-alpha 02版本的RecyclerView。上面的任何版本都是好的:
androidx.recyclerview:recyclerview:1.2.0-alpha02
然后使用筛选的loadStateFlow
将列表滚动到顶部,只在刷新页面并将项放在列表前面时:
viewLifecycleOwner.lifecycleScope.launch {
challengesAdapter.loadStateFlow
.distinctUntilChanged { old, new ->
old.mediator?.prepend?.endOfPaginationReached.isTrue() ==
new.mediator?.prepend?.endOfPaginationReached.isTrue() }
.filter { it.refresh is LoadState.NotLoading && it.prepend.endOfPaginationReached && !it.append.endOfPaginationReached}
.collect {
mBinding.fragmentChallengesByLocationList.scrollToPosition(0)
}
}
GitHub的讨论可以在这里找到:https://github.com/googlecodelabs/android-paging/issues/149
发布于 2022-01-19 20:42:20
adapter.refresh()
lifecycleScope.launch {
adapter.loadStateFlow
.collect {
binding.recycleView.smoothScrollToPosition(0)
}
}
https://stackoverflow.com/questions/65882817
复制相似问题