Paging 库会跟踪分页数据的加载请求状态,并通过 LoadState 类将其公开
。
每个
LoadType和数据源类型
(PagingSource或
RemoteMediator)都会获得一个单独的LoadState信号。监听器提供的
CombinedLoadStates
对象则会提供来自所有这些信号的加载状态的信息。您可以利用此详细信息向用户显示相应的加载指示器。
加载状态
Paging 库通过 LoadState 对象公开要在界面中使用的加载状态。LoadState 对象根据当前的加载状态采用以下三种形式之一:
- 如果没有正在执行的加载操作且没有错误,那么
LoadState为LoadState.NotLoading对象。此子类还包含endOfPaginationReached属性,用于指示是否已到达分页结束处。 - 如果有正在执行的加载操作,那么
LoadState为LoadState.Loading对象。 - 如果出现错误,那么
LoadState为LoadState.Error对象。
您可以通过 loadState 属性访问这些状态。LazyPagingItems您可以通过两种方式使用此状态:处理主要内容的可见性(例如全屏刷新旋转图标),或将加载项直接插入到 LazyColumn 流中(例如页脚旋转图标)。
使用监听器获取加载状态
如需监控界面中的加载状态,请使用 loadState 属性
提供的 LazyPagingItems 封装容器。此属性会返回一个
CombinedLoadStates对象,让您可以针对
刷新、追加或前置事件的加载行为做出响应。
在以下示例中,界面会根据刷新(初始)加载的当前状态显示加载旋转图标或错误消息:
@Composable fun UserListScreen(viewModel: UserViewModel) { val pagingItems = viewModel.flow.collectAsLazyPagingItems() Box(modifier = Modifier.fillMaxSize()) { // Show the list content LazyColumn { items(pagingItems.itemCount) { index -> UserItem(pagingItems[index]) } } // Handle the loading state when (val state = pagingItems.loadState.refresh) { is LoadState.Loading -> { CircularProgressIndicator(modifier = Modifier.align(Alignment.Center)) } is LoadState.Error -> { ErrorButton( message = state.error.message ?: "Unknown error", onClick = { pagingItems.retry() }, modifier = Modifier.align(Alignment.Center) ) } else -> {} // No separate view needed for success/not loading } } }
如需详细了解 LazyPagingItems,请参阅 大型数据集(分页)。
添加加载页眉和页脚
如需在列表的开头或末尾显示加载指示器(充当页眉或页脚),请在 LazyColumn 范围内专门为这些状态添加专用项块。
您可以使用 CombinedLoadStates 对象监控页眉的前置状态和页脚的追加状态。
在以下示例中,当系统提取更多数据时,列表会在底部显示进度条或重试按钮:
@Composable fun UserList(viewModel: UserViewModel) { val pagingItems = viewModel.pager.flow.collectAsLazyPagingItems() LazyColumn { // 1. Header (Prepend state) // Useful if you support bidirectional paging or jumping to the middle item { val prependState = pagingItems.loadState.prepend if (prependState is LoadState.Loading) { LoadingItem() } else if (prependState is LoadState.Error) { ErrorItem( message = prependState.error.message ?: "Error", onClick = { pagingItems.retry() } ) } } // 2. Main Data items(pagingItems.itemCount) { index -> UserItem(pagingItems[index]) } // 3. Footer (Append state) // Shows when the user scrolls to the bottom and more data is loading item { val appendState = pagingItems.loadState.append if (appendState is LoadState.Loading) { LoadingItem() } else if (appendState is LoadState.Error) { ErrorItem( message = appendState.error.message ?: "Error", onClick = { pagingItems.retry() } ) } } } } @Composable fun LoadingItem() { Box(modifier = Modifier.fillMaxWidth().padding(16.dp), contentAlignment = Alignment.Center) { CircularProgressIndicator() } } @Composable fun ErrorItem(message: String, onClick: () -> Unit) { Column( modifier = Modifier.fillMaxWidth().padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Text(text = message, color = Color.Red) Button(onClick = onClick) { Text("Retry") } } }
获取更多加载状态信息
如前面的示例所示,调用 pagingItems.loadState.refresh 非常方便。不过,它会模糊从本地
数据库 (PagingSource) 和
网络 (RemoteMediator) 加载之间的区别。
即使缓存的数据立即可用,这也会导致界面短暂显示加载旋转图标。
如需进行精确控制(例如仅当本地数据库为空且网络同步处于活动状态时才显示加载旋转图标),请直接在可组合项中访问 source 和 mediator 属性。
val loadState = pagingItems.loadState val isSyncing = loadState.mediator?.refresh is LoadState.Loading val isLocalEmpty = loadState.source.refresh is LoadState.NotLoading && pagingItems.itemSnapshotList.items.isEmpty() if (isSyncing && isLocalEmpty) { FullScreenLoading() } else { UserList(pagingItems) if (isSyncing) { TopOverlaySpinner() } }
响应加载状态变化
您可能需要根据加载状态变化触发一次性附带效应,例如滚动到列表顶部或在刷新完成后显示 Snackbar。
在 LaunchedEffect 内使用 snapshotFlow 将状态变化作为流进行观察。这样,您就可以应用标准 Flow 运算符(例如 filter
和 distinctUntilChanged)来隔离特定事件。
val listState = rememberLazyListState() LaunchedEffect(pagingItems) { // 1. Convert the state to a Flow snapshotFlow { pagingItems.loadState.refresh } // 2. Filter for the specific event (Refresh completed successfully) .distinctUntilChanged() .filter { it is LoadState.NotLoading } .collect { // 3. Trigger the side effect listState.animateScrollToItem(0) } }
其他资源
如需详细了解 Paging 库和加载状态,请参阅以下资源。
文档
查看内容
为您推荐
- 注意:当 JavaScript 处于关闭状态时,系统会显示链接文字
- Paging 库概览