搜索无结果/结果过短时隐藏LoadingRow的实现咨询
解决LazyGrid搜索结果不足时显示LoadingRow的问题
针对你遇到的「搜索无结果或结果少于屏幕高度时仍显示LoadingRow」的问题,可以通过多状态组合判断和LazyGrid状态检测来精准控制LoadingRow的显示,具体实现如下:
1. 维护必要的ViewModel状态
确保ViewModel中提供以下状态(以TMDb的分页逻辑为例):
items: 当前已加载的搜索结果列表isLoadingNext: 是否正在加载下一页totalResults: 搜索结果的总数量(从API返回的字段中获取)hasMore: 计算属性,判断是否还有更多数据可加载val hasMore: Boolean get() = items.size < totalResults
2. 检测LazyGrid是否填满屏幕
在LazyTMDbItemGrid中,通过LazyGridState的布局信息判断当前列表是否需要滚动才能显示全部内容:
val listState = rememberLazyGridState() val items = viewModel.items.collectAsState() val isLoadingNext = viewModel.isLoadingNext.collectAsState() val hasMore = viewModel.hasMore val totalItems = items.value.size // 判断列表是否填满屏幕(需要滚动才能看到底部) val isListFilled = remember(listState.layoutInfo, totalItems) { if (totalItems == 0) false else { val visibleItems = listState.layoutInfo.visibleItemsInfo // 若可见item数等于总item数,且最后一个item底部未超出视口 → 列表未填满屏幕 !(visibleItems.size == totalItems && visibleItems.last().offset + visibleItems.last().size <= listState.layoutInfo.viewportEndOffset) } }
3. 控制LoadingRow的显示条件
只有同时满足以下条件时,才显示LoadingRow:
- 还有更多数据可加载(
hasMore为true) - 正在加载下一页(
isLoadingNext为true) - 列表已经填满屏幕(
isListFilled为true,即用户需要滚动才能触达底部)
val shouldShowLoadingRow = hasMore && isLoadingNext.value && isListFilled
4. 实现LazyGrid布局
在LazyVerticalGrid中根据条件渲染LoadingRow,同时处理搜索无结果的空状态:
if (items.value.isEmpty()) { // 搜索无结果时显示空状态提示 EmptySearchPlaceholder() } else { LazyVerticalGrid( state = listState, columns = GridCells.Fixed(2), contentPadding = PaddingValues(8.dp) ) { items(items.value) { item -> TMDbItemCard(item) } // 满足条件才显示加载行 if (shouldShowLoadingRow) { item { LoadingRow() } } } }
5. 优化加载触发逻辑
确保只有用户滚动到接近底部时才触发下一页加载,避免不必要的LoadingRow显示:
LaunchedEffect(listState) { snapshotFlow { listState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0 }.collect { lastVisibleIndex -> // 当滚动到倒数第3个item时,触发下一页加载(可根据需求调整阈值) if (lastVisibleIndex >= totalItems - 3 && hasMore && !isLoadingNext.value) { viewModel.loadNextPage() } } }
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

