1.引用paging3的依赖
def paging_version = "3.0.0-alpha03"
implementation "androidx.paging:paging-runtime:$paging_version"
2.大概的流程图
流程图.jpg由图可知要用paging来分页的话是adapter是要继承PagingDataAdapter或者LoadStateAdapter,目前以PagingDataAdapter为例子。
PagingDataAdapter是通过submitData(PagingData)函数来提交数据到adapter,那么,PagingData又是如何获得呢? 由图可知是通过Pager(PagingConfig(size)) {PageKeyedPagingSource()}.flow 获得 Flow<PagingData>类型的对象,然后通过kotlin协程的flow.collectLatest {adapter.submitData(it)}函数进行数据的订阅。
Fragment的adapter数据提交代码:
lifecycleScope.launchWhenCreated {
homeViewModel.flowData.collectLatest {
homeAdapter.submitData(it)
}
}
viewModel获取 Flow<PagingData>的代码部分:
class HomeViewModel : ViewModel() {
private val _homeRepository = HomeRepository()
val flowData: Flow<PagingData<HomePageRecommend.Item>> =_homeRepository.getFlowPageData()
}
HomeRepository类代码
class HomeRepository {
fun getFlowPageData(): Flow<PagingData<HomePageRecommend.Item>> {
return Pager(PagingConfig(20)) {
PageKeyedPagingSource()
}.flow
}
}
PageKeyedPagingSource 跟 网络接口的定义的 代码的实现:
class PageKeyedPagingSource : PagingSource<String, HomePageRecommend.Item>() {
override suspend fun load(params: LoadParams<String>): LoadResult<String, HomePageRecommend.Item> {
return try {
val page = params.key?:"http://baobab.kaiyanapp.com/api/v5/index/tab/allRec"
//获取网络数据
val result:HomePageRecommend = api.getHomePageRecommend(page)
LoadResult.Page(
//需要加载的数据
data = result.itemList,
//如果可以往上加载更多就设置该参数,否则不设置
prevKey = null,
//加载下一页的key 如果传null就说明到底了
nextKey = if(TextUtils.isEmpty(result.nextPageUrl)|| !result.nextPageUrl?.contains("adIndex")!!) null else result.nextPageUrl
)
}catch (e:Exception){
LoadResult.Error(e)
}
}
}
interface KaiyanApiInterface {
@GET
suspend fun getHomePageRecommend(@Url url:String): HomePageRecommend
}
这里的 val page = params.key?:"http://baobab.kaiyanapp.com/api/v5/index/tab/allRec" 为什么是这样写呢?这是根据后台的返回数据定义的。由于这里的下一页的数据获取是根据上一次后台返回的result.nextPageUrl来获得。
代码地址
网友评论