- val paging_version = "3.2.1"
- implementation("androidx.paging:paging-runtime:$paging_version")
- implementation("androidx.paging:paging-compose:$paging_version")
是对其它数据源的封装,因此和 Repository 定义在同一个 .kt 文件中并私有化。自定义一个类继承 PagingSource 并重写 load() 来提供获取页面数据。
- class DemoRepository {
- fun getData() = Pager(PagingConfig(10)) {
- PagingResource()
- }.flow
- }
-
- private class PagingResource : PagingSource<Int, HotNewestArticleBean.HotNewestArticle.Article>() {
- private val startPage = 0
- override suspend fun load(params: LoadParams<Int>): LoadResult<Int, HotNewestArticleBean.HotNewestArticle.Article> {
- return try {
- val currentPage = params.key ?: startPage
- val data = getData(currentPage)
- val prevKey = if (currentPage > startPage) currentPage - 1 else null
- val nextKey = if (data.isNotEmpty()) currentPage + 1 else null
- LoadResult.Page(data, prevKey, nextKey)
- } catch (e: Exception) {
- LoadResult.Error(e)
- }
- }
-
- override fun getRefreshKey(state: PagingState<Int, HotNewestArticleBean.HotNewestArticle.Article>): Int? {
- return null
- }
-
- //具体获取数据的方法。这里能更细分的对异常处理,否则在load()中合并返回后在UI中难区分。
- //但处理后还是要抛出异常,不然load()不会返回异常,影响UI中对Paging状态判断
- private suspend fun getData(currentPage: Int): List
{ - var data: List
= emptyList() - runCatching {
- withContext(Dispatchers.IO) {
- RetrofitClient.apiService.newestArticle(currentPage.toString())
- }
- }.onSuccess { response ->
- response.getData().onSuccess {
- data = it.datas
- }.onFailure {
- Log.e("服务器错误", it.message.toString())
- throw Exception("服务器错误:${it.message}")
- }
- }.onFailure {
- Log.e("本地错误", it.message.toString())
- throw Exception("本地错误:${it.message}")
- }
- return data
- }
- }
- class DemoViewModel : ViewModel() {
- private val repository = DemoRepository()
- var pagingDataFlow = repository.getData().cachedIn(viewModelScope) //缓存在ViewModel中
- }
- @Composable
- fun DemoScreen(
- viewModel: DemoViewModel = viewModel()
- ) {
- //将Paging的数据从Flow转为可供LazyColumn使用的
- val lazyPagingItems = viewModel.pagingDataFlow.collectAsLazyPagingItems()
- //监听Paging状态
- when (lazyPagingItems.loadState.refresh) {
- //正在加载
- is LoadState.Loading -> {}
- //加载错误(这里的错误是PagingSource里捕获的)
- is LoadState.Error -> {}
- //当没有加载动作并且没有错误的时候
- is LoadState.NotLoading -> {}
- }
- LazyColumn(
- modifier = Modifier.fillMaxSize(),
- state = lazyListState
- ){
- items(
- count = lazyPagingItems.itemCount,
- key = lazyPagingItems.itemKey { it.id }
- ) { index ->
- val bean = lazyPagingItems[index]
- if (bean != null) {
- val author = bean.author
- val shareUser = bean.shareUser
- val superChapterName = bean.superChapterName
- Item(
- title = bean.title,
- author = if (author.isEmpty()) String.format("%s · %s", superChapterName, shareUser) else String.format("%s · %s", superChapterName, author),
- time = bean.niceDate,
- )
- } else {
- Text("")
- }
- }
- }
- }