问题描述
我正在使用一个 rest API,它使用基于游标的分页来显示一些结果.我想知道是否可以使用 Paging Library 3.0 进行分页它.我一直在浏览一些媒体和文档,但似乎找不到实现它的方法.如果你们中的任何人找到了任何解决方案,我会很高兴收到它!
I am consuming a rest API that uses cursor based pagination to show some results. I am wondering if I can use Paging Library 3.0 to paginate it. I have been looking through some mediums and docs and can't seem to find a way to implement it. If any of you has come around any solution, I would be so happy to hear from it!
api 响应分页如下所示:
The api response pagination looks like this:
"paging": {
"previous": false,
"next": "https://api.acelerala.com/v1/orders/?store_id=4&after=xyz",
"cursors": {
"before": false,
"after": "xyz"
}
}
推荐答案
感谢 @Đặng Anh Hào,我得以走上正轨.由于我的光标是一个 String 而不是 Int,Paging Source 加载函数看起来像这样:
Thanks to @Đặng Anh Hào I was able to get on track. As my cursor is a String and not at Int, the Paging Source load function looks like this:
override suspend fun load(params: LoadParams<String>): LoadResult<String, Order> {
return try{
val response = service.getOrders(query,params.key?:"",10)
val nextKey = if(response.paging?.cursors?.after=="false") null else response.paging?.cursors?.after
val prevKey = if(response.paging?.cursors?.before=="false") null else response.paging?.cursors?.before
LoadResult.Page(response.data?.toOrderList()?:emptyList(),prevKey,nextKey)
}catch (exception: IOException) {
LoadResult.Error(exception)
} catch (exception: retrofit2.HttpException) {
LoadResult.Error(exception)
}
}
并且 onrefreshkey 看起来像这样:
and the onrefreshkey looks like this:
override fun getRefreshKey(state: PagingState<String, Order>): String? {
return state.anchorPosition?.let {
state.closestItemToPosition(it)?.orderId
}
}
存储库方法如下所示:
fun getOrdersPaginated(storeId: String): Flow<PagingData<Order>> {
return Pager(
config = PagingConfig(enablePlaceholders = false,pageSize = 10),
pagingSourceFactory = {PagingSource(apiService,storeId)}
).flow
}
而View Model方法是这样的:
And the View Model method is like this:
private val _pagedOrders = MutableLiveData<PagingData<Order>>()
val orders get() = _pagedOrders
private var currentQueryValue: String? = null
private var currentSearchResult: Flow<PagingData<Order>>? = null
fun getOrdersPaginated(storeId: String) {
viewModelScope.launch {
currentQueryValue = storeId
val newResult: Flow<PagingData<Order>> = repository.getOrdersPaginated(storeId)
.cachedIn(viewModelScope)
currentSearchResult = newResult
currentSearchResult!!.collect {
_pagedOrders.value = it
}
}
}
活动像这样调用分页:
private var searchJob: Job? = null
private fun getOrders() {
viewModel.getOrdersPaginated(storeId)
}
private fun listenForChanges() {
viewModel.orders.observe(this, {
searchJob?.cancel()
searchJob = lifecycleScope.launch {
ordersAdapter.submitData(it)
}
})
}
最后,适配器与 ListAdapter 相同,唯一不同的是它现在扩展了 PagingDataAdapter(OrdersDiffer)
And finally the adapter is the same as a ListAdapter, the only thing that changes is that it now extends PagingDataAdapter<Order, OrderAdapter.ViewHolder>(OrdersDiffer)
有关如何操作的更详细教程,我阅读了此代码实验室一个>
For a more detailed tutorial on how to do it, I read this codelab
这篇关于有没有办法在 Android 中使用 Paging Library 3.0 实现基于游标的分页?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!