在 Compose 中使用 Paging 分页库 | 开发者说·DTalk
The following article is from Android技术圈 Author 黄林晴
Paging 3 的使用
项目搭建
implementation("androidx.paging:paging-compose:1.0.0-alpha14")implementation "com.squareup.retrofit2:retrofit:2.9.0"implementation "com.squareup.retrofit2:converter-gson:2.9.0"implementation "com.squareup.okhttp3:logging-interceptor:4.9.2"implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.4.1"API 接口准备
object RetrofitService {
/** * okhttp client */ lateinit var okHttpClient: OkHttpClient
/** * 主Url地址 */ private const val BASEAPI = "https://www.wanandroid.com/";
/** * 创建service对象 */ fun <T> createService(mClass: Class<T>): T { val builder: OkHttpClient.Builder = OkHttpClient.Builder(); okHttpClient = builder.build() val retrofit: Retrofit = Retrofit.Builder() .baseUrl(BASEAPI) .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .build() return retrofit.create(mClass) as T }
}interface DataApi {
/** * 获取数据 */ @GET("wenda/list/{pageId}/json") suspend fun getData(@Path("pageId") pageId:Int): DemoReqData}定义数据源
class DataSource():PagingSource<Int,DemoReqData.DataBean.DatasBean>(){ override suspend fun load(params: LoadParams<Int>): LoadResult<Int, DemoReqData.DataBean.DatasBean> { TODO("Not yet implemented") }
override fun getRefreshKey(state: PagingState<Int, DemoReqData.DataBean.DatasBean>): Int? { return null }}getRefreshKey 方法是新增的,之前没有提到过,这里讲解一下这个方法的用途。
getRefreshKey 方法意思是 refresh 时,从最后请求的页面开始请求,null 则请求第一页。
class ADataSource : PagingSource<Int, DemoReqData.DataBean.DatasBean>() { override suspend fun load(params: LoadParams<Int>): LoadResult<Int, DemoReqData.DataBean.DatasBean> {
return try {
//页码未定义置为1 val currentPage = params.key ?: 1 //仓库层请求数据 Log.d("请求页码标记", "请求第${currentPage}页") val demoReqData = DataRespority().loadData(currentPage) //当前页码 小于 总页码 页面加1 val nextPage = if (currentPage < demoReqData.data?.pageCount ?: 0) { currentPage + 1 } else { //没有更多数据 null }
LoadResult.Page( data = demoReqData.data!!.datas!!, prevKey = null, nextKey = nextPage )
} catch (e: Exception) { if (e is IOException) { Log.d("测试错误数据", "-------连接失败") } Log.d("测试错误数据", "-------${e.message}") LoadResult.Error(throwable = e) }
}
override fun getRefreshKey(state: PagingState<Int, DemoReqData.DataBean.DatasBean>): Int? { return null }
}class DataRespority {
private var netWork = RetrofitService.createService( DataApi::class.java )
/** * 查询护理数据 */ suspend fun loadData( pageId: Int ): DemoReqData? { return try { netWork.getData(pageId) } catch (e: Exception) { //在这里处理或捕获异常 null }
}}创建 viewmodel
创建 viewModel 对象,并创建 pager 对象从而调用 PagingSource 方法,代码如下所示:
class MainActivityViewModel : ViewModel() {
/** * 获取数据 */ fun getData() = Pager(PagingConfig(pageSize = 1)) { DataSource() }.flow}实现 UI 层代码
View 层数据请求并将结果显示在 View 上
val mainViewmodel: MainActivityViewModel = viewModel()val data = mainViewmodel.getData().collectAsLazyPagingItems()implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.4.1" Column { LazyColumn() { items(items = data) { item -> Message(data = item) } } }Message 是数据展示页面对应的 compose 函数,代码如下所示:
@Composablefun Message(data: DemoReqData.DataBean.DatasBean?) { Card( modifier = Modifier .background(Color.White) .padding(10.dp) .fillMaxSize(), elevation = 10.dp ) { Column(modifier = Modifier.padding(10.dp)) { Text( text = "作者:${data?.author}" ) Text(text = "${data?.title}") } }}监听 Paging 3 状态
if (data.loadState.refresh is LoadState.Loading) { Log.d(TAG, "正在加载")} else if (data.loadState.refresh is LoadState.Error) { when ((data.loadState.refresh as LoadState.Error).error) { is IOException -> { Log.d(TAG, "网络未连接,可在这里放置失败视图") } else -> { Log.d(TAG, "网络未连接,其他异常") } }}@Composablefun Greeting() { val mainViewmodel: MainActivityViewModel = viewModel() val data = mainViewmodel.getData().collectAsLazyPagingItems() Column { LazyColumn() { items(items = data) { item -> Message(data = item) }
val TAG = "加载状态"
if (data.loadState.refresh is LoadState.Loading) { Log.d(TAG, "正在加载") } else if (data.loadState.refresh is LoadState.Error) { when ((data.loadState.refresh as LoadState.Error).error) { is IOException -> { Log.d(TAG, "网络未连接,可在这里放置失败视图") } else -> { Log.d(TAG, "网络未连接,其他异常") } } } } }
}
@Composablefun Message(data: DemoReqData.DataBean.DatasBean?) { Card( modifier = Modifier .background(Color.White) .padding(10.dp) .fillMaxSize(), elevation = 10.dp ) { Column(modifier = Modifier.padding(10.dp)) { Text( text = "作者:${data?.author}" ) Text(text = "${data?.title}") } }
}https://github.com/huanglinqing123/ComposePagingDemo
长按右侧二维码
查看更多开发者精彩分享
"开发者说·DTalk" 面向