code小生 一个专注大前端领域的技术平台公众号回复Android
加入安卓技术群
作者:柠檬茶就是力量
链接:https://juejin.im/post/5ee74d216fb9a047f012853e
声明:本文来自柠檬茶就是力量
投稿,转发等请联系原作者授权
上个周末晚上看到了鸿洋大神的公众号推送文章<<Jetpack重磅更新>>,于是乎点开文章看了一下具体内容,在翻阅的过程中发现
Paging 3.0
的信息,因为以前写过旧版Paging
的demo,但是当时觉得Paging
并不是很好用就放弃了,所以这次更新了Paging 3.0
所以第一时间到官网看一下介绍然后写了个简单的小Demo来熟悉一下这个新的Paging
库
介绍
官方文档:https://developer.android.com/topic/libraries/architecture/paging/v3-overview
作为一个RecyclerView
相关的库,Paging 3.0
处理了关于数据加载,loadmore,refresh等功能,具体有以下这些功能和优点,可以减少代码中的逻辑处理和封装
记录上一页和下一页的key,也就是我们常用的分页加载中的page
滚动到底部的时候自动开启请求下一页的数据
确保不会同时触发多个请求
允许缓存数据:如果使用的是Kotlin,则可以通过
CoroutineScope
来完成;如果使用的是Java,则可以用LiveData
。跟踪加载数据的状态,比如
重试
刷新
等可以用
map
filter
等操作符处理数据提供方法实现简单的分割线
实现步骤
1.创建数据源PagingSource
首先我们需要创建一个数据源PagingSource
来给Paging
提供源数据,这里用wanAndroid的接口来做测试,网络请求用Retrofit
和协程来处理,具体相关代码就不贴在下面了
class MainSource : PagingSource<Int, ArticleEntity>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, ArticleEntity> {
// 如果key是null,那就加载第0页的数据
val page = params.key ?: 0
return try {
// 这里获取文章列表的response
val response = Api.getHomeArticles(page)
LogUtils.d("加载第$page 页")
// 如果成功加载,那么返回一个LoadResult.Page,如果失败就返回一个Error
// Page里传进列表数据,以及上一页和下一页的页数,具体的是否最后一页或者其他逻辑就自行判断
// 需要注意的是,如果是第一页,prevKey就传null,如果是最后一页那么nextKey也传null
// 其他情况prevKey就是page-1,nextKey就是page+1
LoadResult.Page(
data = response.pageData(),
prevKey = if (page == 0) null else page - 1,
nextKey = if (response.isLastPage()) null else page + 1
)
} catch (e: Exception) {
// 捕获异常,返回一个Error
LoadResult.Error(e.toKError())
}
}
}
2. PagingData
和Pager
PagingData
是数据源和RecyclerView Adapter
之间的一个桥梁,每一页数据就是一个PagingData
首先创建Flow<PagingData<XXX>>
,可以通过Pager().flow()
去实现,可以传入PagingConfig
到Pager
中去设置一些分页的参数,比如:
pageSize
: 每一页的数据量prefetchDistance
: 预取数据的距离,也就是距离最后一个item多