分页3中间刷新

问题描述 投票:0回答:1

我在刷新分页数据时遇到问题,并且不确定需要如何设置刷新键才能正常工作。文档根本不清楚。 我有这个用于偏移分页的基类,所以它是 0-40、40-60、60-80 等等。这可行,但是当我在集合中间并且我想使用 invalidate() 或adapter.refresh() 刷新数据时,它会崩溃并显示以下消息:

java.lang.IllegalStateException: The same value, 40, was passed as the prevKey in two sequential Pages loaded from a PagingSource. Re-using load keys in PagingSource is often an error, and must be explicitly enabled by overriding PagingSource.keyReuseSupported.

启用后,它不会崩溃,但它的行为很奇怪,因为它从中间开始分页,我无法返回到集合的开头,因为它不断地分页相同的项目。

示例:

prevKey null, nextKey: 40 -> prevKey 40, nextKey: 60 -> prevKey 60, 下一个键:80

无效()

prevKey 40, nextKey: 80 -> prevKey 40, nextKey: 60 // 是这样的 当它在没有 keyReuseSupported 标志的情况下崩溃时。

当我想回到开头时,它卡在了 prevKey 40,nextKey:60

abstract class OffsetPagingSource<Value : Any>(
    private val coroutineScope: CoroutineScope
) : PagingSource<Int, Value>() {

    abstract suspend fun queryFactory(
        size: Int,
        after: Int,
        itemCount: Boolean
    ): PagingResult<Value>?

    abstract suspend fun subscriptionFactory(): Flow<Any>?

    init {
        initSubscription()
    }

    private fun initSubscription() {
        coroutineScope.launch {
            try {
                subscriptionFactory()?.collect {
                    invalidate()
                }
            } catch (e: Throwable) {}
        }
    }

    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Value> {
        val size = params.loadSize
        val after = params.key ?: 0

        return try {
            val result = queryFactory(size, after, true) ?: return LoadResult.Page(emptyList(), null, null)

            val totalCount = result.pageInfo.itemCount

            val nextCount = after + size

            val prevKey = if (after == 0) null else after
            val nextKey = if (nextCount < totalCount) nextCount else null

            LoadResult.Page(result.edges.mapNotNull { it.node }, prevKey = prevKey, nextKey)
        } catch (e: Exception) {
            LoadResult.Error(e)
        }
    }

    override fun getRefreshKey(state: PagingState<Int, Value>): Int? {
        return state.anchorPosition?.let { anchorPosition ->
            val anchorPage = state.closestPageToPosition(anchorPosition)
            anchorPage?.prevKey
        }
    }
}

有人知道如何解决这个问题吗?我不确定这是否是一个错误。分页 3 种强制分页工作方式,而不是启用不同的方法。

android android-paging-3
1个回答
0
投票

抛出的异常警告您正在使用相同的密钥加载不同的数据/页面。在您的示例中,无效后:

{ prevKey 40, nextKey: 80}, { prevKey 40, nextKey: 60 }

表示您希望对第一页之前的页面使用

params.key = 40
并重新加载第一页。也就是说,你有:

page0: not loaded yet
page1: { prevKey 40, nextKey: 80 }
page2: { prevKey 40, nextKey: 60 }

表示您要使用

params.key
加载 page0 和 page1。这可能是您想要的,但通常是一个错误,这就是该异常警告您的内容。

您可能一遍又一遍地重新加载同一页面的原因是,您使用从

key...key+pageSize
加载并始终传递
prevKey
=
key
的相同逻辑来解释前置和附加。您可能需要检查
LoadParams is LoadParams.Prepend
并在
load
逻辑中偏移该键,或者在将其作为
prevKey
返回到 Paging 之前偏移该键。

© www.soinside.com 2019 - 2024. All rights reserved.