有没有办法在 Android 中使用 Paging Library 3.0 实现基于游标的分页? [英] Is there a way to implement a cursor based pagination with Paging Library 3.0 in Android?

查看:26
本文介绍了有没有办法在 Android 中使用 Paging Library 3.0 实现基于游标的分页?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个 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(O​​rdersDiffer)

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 实现基于游标的分页?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆