Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/207.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 第3页-如何在PagingDataAdapter完成刷新且DiffUtil完成差异化后滚动到RecyclerView顶部?_Android_Paging_Android Paging_Android Paging Library_Android Paging 3 - Fatal编程技术网

Android 第3页-如何在PagingDataAdapter完成刷新且DiffUtil完成差异化后滚动到RecyclerView顶部?

Android 第3页-如何在PagingDataAdapter完成刷新且DiffUtil完成差异化后滚动到RecyclerView顶部?,android,paging,android-paging,android-paging-library,android-paging-3,Android,Paging,Android Paging,Android Paging Library,Android Paging 3,我正在使用带RemoteMediator的分页3,它在从网络获取新数据时显示缓存数据。 当我刷新我的PagingDataAdapter(通过在其上调用refresh())时,我希望我的RecyclerView在刷新完成后滚动到顶部。在中,他们尝试通过以下方式通过loadStateFlow处理此问题: lifecycleScope.launch { adapter.loadStateFlow // Only emit when REFRESH LoadState f

我正在使用带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完成diffing时收到通知。但这将导致适配器加载状态的
PREPEND
APPEND
出现各种竞争条件,这也会导致DiffUtil运行(但这里我们不想滚动到顶部)


一个可行的解决方案是将
PagingData.empty()
传递给
PagingDataAdapter
,然后重新运行相同的查询(只调用
refresh
将不起作用,因为
PagingData
现在为空,没有任何内容可刷新)但是我更愿意让我的旧数据保持可见,直到我知道刷新实际上成功为止。

查看一下代码,如果loadtype被刷新,那么条件是什么

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)
        }
如果LoadType为refresh清除所有表,则应删除该条件

if (loadType == LoadType.REFRESH) {
            repoDatabase.remoteKeysDao().clearRemoteKeys()
            repoDatabase.reposDao().clearRepos()
        }
 

我已经设法改进了主题问题中的基本代码片段。 关键是监听
CombinedLoadState

viewLifecycleOwner.lifecycleScope.launchWhenCreated {
            adapter?.loadStateFlow
                ?.distinctUntilChanged { old, new ->
                    old.mediator?.prepend?.endOfPaginationReached.isTrue() ==
                            new.mediator?.prepend?.endOfPaginationReached.isTrue()
                }
                ?.filter { it.refresh is LoadState.NotLoading }
                ..
                // next flow pipeline operators
        }
其中
isTrue
是布尔扩展

fun Boolean?.isTrue() = this != null && this
因此,这里的想法是跟踪
mediator.prepend:endOfPagination
标志状态。当mediator完成了当前页面的分页加载部分时,他的
prepend
状态不会改变(如果您在向下滚动后加载页面)。 该解决方案在离线和在线模式下都运行良好


若您需要在两个方向上跟踪前置分页或分页,那个么在搜索静态内容等情况下,使用另一个
组合加载状态
属性
附加
刷新
中介
是一个很好的起点,我们可以在
DiffUtil.ItemCallback
AreItemsSame
中返回
false
,作为解决方法。我也用它来更改排序属性。

你找到解决方案了吗?@P1NG2WIN没有,我现在用的是300毫秒的延迟,这有点糟糕:(我将对此提出问题。)then@P1NG2WIN您是否创建了问题?如果是,是否可以链接到此处?