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協(xié)程的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來獲得。
代碼地址