Android Sunflower Paging 3高级用法:自定义加载状态

Android Sunflower Paging 3高级用法:自定义加载状态

【免费下载链接】sunflower A gardening app illustrating Android development best practices with migrating a View-based app to Jetpack Compose. 【免费下载链接】sunflower 项目地址: https://gitcode.com/gh_mirrors/su/sunflower

你还在为Paging 3加载状态处理烦恼吗?本文以Sunflower项目为例,详细讲解如何在Jetpack Compose中实现自定义加载状态,包括加载中、错误处理和空数据展示。读完本文你将掌握:

  • PagingSource自定义实现
  • ViewModel中的状态管理
  • Compose UI加载状态处理
  • 下拉刷新与错误重试机制

Paging 3架构概览

Paging 3是Android Jetpack组件库中用于高效加载分页数据的解决方案。在Sunflower项目中,图片画廊功能通过Paging 3实现网络图片的分页加载,核心实现位于以下文件:

Paging 3架构

自定义PagingSource实现

PagingSource是数据源的核心,负责定义如何从网络或数据库加载数据。Sunflower项目中的UnsplashPagingSource实现了从Unsplash API加载图片的逻辑:

class UnsplashPagingSource(
    private val service: UnsplashService,
    private val query: String
) : PagingSource<Int, UnsplashPhoto>() {
    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, UnsplashPhoto> {
        val page = params.key ?: UNSPLASH_STARTING_PAGE_INDEX
        return try {
            val response = service.searchPhotos(query, page, params.loadSize)
            LoadResult.Page(
                data = response.results,
                prevKey = if (page == UNSPLASH_STARTING_PAGE_INDEX) null else page - 1,
                nextKey = if (page == response.totalPages) null else page + 1
            )
        } catch (exception: Exception) {
            LoadResult.Error(exception)  // 错误状态处理
        }
    }
}

关键实现说明:

  1. 分页参数:通过params.key获取当前页码,默认为起始页
  2. 数据加载:调用UnsplashService获取分页数据
  3. 状态返回:成功时返回LoadResult.Page,错误时返回LoadResult.Error

ViewModel中的状态管理

GalleryViewModel负责将Paging数据流转换为UI可观察的状态:

class GalleryViewModel @Inject constructor(
    private val repository: UnsplashRepository
) : ViewModel() {
    private val _plantPictures = MutableStateFlow<PagingData<UnsplashPhoto>?>(null)
    val plantPictures: Flow<PagingData<UnsplashPhoto>> get() = _plantPictures.filterNotNull()

    fun refreshData() {
        viewModelScope.launch {
            _plantPictures.value = repository.getSearchResultStream(queryString ?: "").cachedIn(viewModelScope).first()
        }
    }
}

核心逻辑:

  • 使用MutableStateFlow存储分页数据
  • 通过cachedIn(viewModelScope)确保配置变更时数据不丢失
  • 提供refreshData()方法支持手动刷新

Compose UI加载状态处理

GalleryScreen实现了完整的加载状态UI,包括下拉刷新和错误处理:

@Composable
private fun GalleryScreen(
    plantPictures: Flow<PagingData<UnsplashPhoto>>,
    onPullToRefresh: () -> Unit,
) {
    val pagingItems: LazyPagingItems<UnsplashPhoto> = plantPictures.collectAsLazyPagingItems()
    val pullToRefreshState = rememberPullToRefreshState()

    LaunchedEffect(pagingItems.loadState) {
        when (pagingItems.loadState.refresh) {
            is LoadState.Loading -> Unit  // 下拉刷新中
            is LoadState.Error, LoadState.NotLoading -> pullToRefreshState.endRefresh()
        }
    }

    Box(modifier = Modifier.nestedScroll(pullToRefreshState.nestedScrollConnection)) {
        LazyVerticalGrid(columns = GridCells.Fixed(2)) {
            items(count = pagingItems.itemCount) { index ->
                val photo = pagingItems[index] ?: return@items
                PhotoListItem(photo = photo)
            }
        }

        PullToRefreshContainer(
            modifier = Modifier.align(Alignment.TopCenter),
            state = pullToRefreshState
        )
    }
}

加载状态处理策略

状态类型处理方式对应代码位置
加载中显示下拉刷新动画GalleryScreen.kt#L89-L91
加载完成隐藏刷新动画并更新列表GalleryScreen.kt#L96-L103
加载错误记录异常并允许重试UnsplashPagingSource.kt#L40-L42

加载状态演示

高级扩展:错误状态自定义

要实现更友好的错误提示,可以扩展LoadState.Error处理逻辑:

when (val state = pagingItems.loadState.refresh) {
    is LoadState.Error -> {
        ErrorView(
            message = state.error.localizedMessage,
            onRetry = { pagingItems.retry() }
        )
    }
}

建议在项目中添加错误视图组件,位置参考:app/src/main/java/com/google/samples/apps/sunflower/compose/utils/

总结与最佳实践

  1. 状态隔离:通过ViewModel分离UI状态与数据加载逻辑
  2. 错误边界:在PagingSource中捕获所有网络异常
  3. 用户体验:始终提供加载状态反馈和重试机制
  4. 性能优化:使用cachedIn(viewModelScope)避免重复请求

完整实现可参考Sunflower项目的Gallery模块,建议结合官方文档Paging 3指南深入学习。

点赞收藏本文,下期将带来"Paging 3与Room数据库结合实战",敬请关注!

【免费下载链接】sunflower A gardening app illustrating Android development best practices with migrating a View-based app to Jetpack Compose. 【免费下载链接】sunflower 项目地址: https://gitcode.com/gh_mirrors/su/sunflower

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值