我在刷新分页数据时遇到问题,并且不确定需要如何设置刷新键才能正常工作。文档根本不清楚。 我有这个用于偏移分页的基类,所以它是 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 种强制分页工作方式,而不是启用不同的方法。
抛出的异常警告您正在使用相同的密钥加载不同的数据/页面。在您的示例中,无效后:
{ 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 之前偏移该键。