首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >分页3-如何滚动到RecyclerView顶部,在PagingDataAdapter完成刷新和DiffUtil已经完成扩展之后?

分页3-如何滚动到RecyclerView顶部,在PagingDataAdapter完成刷新和DiffUtil已经完成扩展之后?
EN

Stack Overflow用户
提问于 2021-01-25 10:19:59
回答 6查看 4.9K关注 0票数 10

我在RemoteMediator中使用分页3,它显示缓存的数据,同时从网络中获取新的数据。当我刷新我的PagingDataAdapter (通过在它上调用refresh() )时,我希望我的RecyclerView在刷新完成后滚动到顶部。在码标中,他们试图通过loadStateFlow以以下方式处理这一问题:

代码语言:javascript
运行
复制
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完成扩展时得到通知。但是这将导致适配器的PREPENDAPPEND加载状态下的各种争用条件,这也会导致DiffUtil运行(但这里我们不想滚动到顶部)。

一种可行的解决方案是将PagingData.empty()传递给PagingDataAdapter并重新运行相同的查询(只调用refresh将无法工作,因为PagingData现在是空的,没有什么可刷新的),但我更愿意在知道刷新实际上成功之前保持旧数据可见。

EN

回答 6

Stack Overflow用户

发布于 2021-06-18 17:01:11

在搜索静态内容的情况下,我们可以在false of DiffUtil.ItemCallback中返回DiffUtil.ItemCallback作为解决方案。我也使用它来更改排序属性。

票数 3
EN

Stack Overflow用户

发布于 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,所以导入:

代码语言:javascript
运行
复制
androidx.paging:paging-runtime-ktx:3.1.0-alpha03

然后将适配器的恢复策略设置为:

代码语言:javascript
运行
复制
adapter.stateRestorationPolicy = RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY

如果对上述更改有编译错误,请确保至少使用1.2.0-alpha 02版本的RecyclerView。上面的任何版本都是好的:

代码语言:javascript
运行
复制
androidx.recyclerview:recyclerview:1.2.0-alpha02

然后使用筛选的loadStateFlow将列表滚动到顶部,只在刷新页面并将项放在列表前面时:

代码语言:javascript
运行
复制
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

票数 3
EN

Stack Overflow用户

发布于 2022-01-19 20:42:20

代码语言:javascript
运行
复制
adapter.refresh()
lifecycleScope.launch {
    adapter.loadStateFlow
    .collect {                  
        binding.recycleView.smoothScrollToPosition(0)                           
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65882817

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档