如何在 Android 中停止循环相同的回收器视图数据?
How to stop looping same recycler view data in Android?
在我的 API 中,没有 pageSize 或每个产品的唯一 ID,但我仍然在适配器内部实现了 Paging 3 库和比较器以及最新更改的实时数据。
现在的问题是:假设我的 API 中总共只有 10 个项目,我将其提取并显示在列表中。但是,一旦我滚动 10 个项目,就会再次显示 10 个项目,然后再次......无限!!
我怀疑我有 3 个错误,一个是因为分页实现错误(下一个上一个键),或者第二个问题是因为比较器和第三个,我覆盖了 getRefreshKey 并传递了 state.anchorPosition。
代码:
ProductPagingSource
class ProductPagingSource(
private val productApi: ProductApi,
) : PagingSource<Int, Products>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Products> {
val position = params.key ?: PRODUCT_STARTING_PAGE_INDEX
return try {
val response =
productApi.getProducts() //Not added load size, position and other params, because in API, there is no data related to that.
val products = response.products
LoadResult.Page(
data = products,
prevKey = if (position == PRODUCT_STARTING_PAGE_INDEX) null else position - 1,
nextKey = if (products.isEmpty()) null else position + 1
)
} catch (exception: IOException) {
LoadResult.Error(exception)
} catch (exception: HttpException) {
LoadResult.Error(exception)
}
}
override fun getRefreshKey(state: PagingState<Int, Products>): Int? {
return state.anchorPosition
}
}
产品适配器
class ProductAdapter(context: Context?) :
PagingDataAdapter<Products, ProductAdapter.ProductViewHolder>(PRODUCT_COMPARATOR) {
private lateinit var mContext: Context
init {
if (context != null) {
mContext = context
}
}
.
.
.
private val PRODUCT_COMPARATOR = object : DiffUtil.ItemCallback<Products>() {
override fun areItemsTheSame(oldItem: Products, newItem: Products) =
oldItem.name == newItem.name
override fun areContentsTheSame(oldItem: Products, newItem: Products) =
oldItem == newItem
}
}
}
没有API文档,我只能笼统地回答这个问题:
当你告诉它总是获取相同的数据时,它可能总是获取相同的数据 - 这意味着我们的业务逻辑存在缺陷,因为 productApi.getProducts()
需要获取每个键(通常称为“下一页标记”)。如果 API 不支持分页,您必须使用存储库,然后查询支持分页的本地 SQLite。
在我的 API 中,没有 pageSize 或每个产品的唯一 ID,但我仍然在适配器内部实现了 Paging 3 库和比较器以及最新更改的实时数据。
现在的问题是:假设我的 API 中总共只有 10 个项目,我将其提取并显示在列表中。但是,一旦我滚动 10 个项目,就会再次显示 10 个项目,然后再次......无限!!
我怀疑我有 3 个错误,一个是因为分页实现错误(下一个上一个键),或者第二个问题是因为比较器和第三个,我覆盖了 getRefreshKey 并传递了 state.anchorPosition。
代码:
ProductPagingSource
class ProductPagingSource(
private val productApi: ProductApi,
) : PagingSource<Int, Products>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Products> {
val position = params.key ?: PRODUCT_STARTING_PAGE_INDEX
return try {
val response =
productApi.getProducts() //Not added load size, position and other params, because in API, there is no data related to that.
val products = response.products
LoadResult.Page(
data = products,
prevKey = if (position == PRODUCT_STARTING_PAGE_INDEX) null else position - 1,
nextKey = if (products.isEmpty()) null else position + 1
)
} catch (exception: IOException) {
LoadResult.Error(exception)
} catch (exception: HttpException) {
LoadResult.Error(exception)
}
}
override fun getRefreshKey(state: PagingState<Int, Products>): Int? {
return state.anchorPosition
}
}
产品适配器
class ProductAdapter(context: Context?) :
PagingDataAdapter<Products, ProductAdapter.ProductViewHolder>(PRODUCT_COMPARATOR) {
private lateinit var mContext: Context
init {
if (context != null) {
mContext = context
}
}
.
.
.
private val PRODUCT_COMPARATOR = object : DiffUtil.ItemCallback<Products>() {
override fun areItemsTheSame(oldItem: Products, newItem: Products) =
oldItem.name == newItem.name
override fun areContentsTheSame(oldItem: Products, newItem: Products) =
oldItem == newItem
}
}
}
没有API文档,我只能笼统地回答这个问题:
当你告诉它总是获取相同的数据时,它可能总是获取相同的数据 - 这意味着我们的业务逻辑存在缺陷,因为 productApi.getProducts()
需要获取每个键(通常称为“下一页标记”)。如果 API 不支持分页,您必须使用存储库,然后查询支持分页的本地 SQLite。