You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose分页加载时LazyVerticalStaggeredGrid消失求助

Jetpack Compose分页加载时LazyVerticalStaggeredGrid消失问题解决

问题核心原因

触发加载后Grid消失的根本问题在于ViewModel的状态更新逻辑错误:
当收到ResponseEvent.Loading事件时,你直接创建了新的UiState(loading = true)实例,而UiState的默认list是空列表,这会直接清空原有数据,导致LazyVerticalStaggeredGrid因无数据可渲染而消失,仅剩下加载指示器。
此外,当前代码缺少加载成功时的数据追加逻辑,无法将新获取的分页数据合并到原有列表中。

修复方案

1. 修正ViewModel的状态更新逻辑

使用copy()方法更新UiState,保留原有状态的属性,仅修改需要更新的字段,避免清空已有数据:

fun getPhotos() = viewModelScope.launch {
    photosRepository.getPhotos(accessKey = ConstantUrls.ACCESS_KEY, pageNo = pageNo++) { event ->
        when(event) {
            is ResponseEvent.Failure -> {
                _uiStateFlow.update { 
                    it.copy(error = event.error, loading = false)
                }
            }
            ResponseEvent.Loading -> {
                _uiStateFlow.update { 
                    it.copy(loading = true) // 仅切换加载状态,保留原有列表数据
                }
            }
            is ResponseEvent.Success -> { // 补充成功事件处理,追加新数据
                _uiStateFlow.update { 
                    it.copy(
                        loading = false,
                        list = it.list + event.data,
                        error = null
                    )
                }
            }
        }
    }
}

2. 修正初始化时的状态更新逻辑

初始化读取本地数据时,同样使用copy()保留原有状态:

init {
    viewModelScope.launch {
        photosRepository.getAllPhotos().collectLatest { list ->
            if (list.isEmpty()) {
                getPhotos()
            } else {
                _uiStateFlow.update { 
                    it.copy(list = list)
                }
            }
        }
    }
}

3. 优化加载触发逻辑(可选)

将底部触发加载的逻辑放到LaunchedEffect中,避免重组时重复执行:

@Composable
fun PhotosGrid(
    modifier: Modifier,
    lazyListState: LazyStaggeredGridState = rememberLazyStaggeredGridState(),
    list: List<PhotosModel>,
    loading: Boolean = false,
    loadMore: () -> Unit
) {
    val reachedBottom: Boolean by remember { derivedStateOf { lazyListState.reachedBottom() } }

    // 用LaunchedEffect控制触发时机
    LaunchedEffect(reachedBottom, loading) {
        if (reachedBottom && !loading) {
            Log.d(TAG, "View: reached bottom")
            loadMore()
        }
    }

    LazyVerticalStaggeredGrid(
        modifier = modifier,
        columns = StaggeredGridCells.Fixed(2),
        horizontalArrangement = Arrangement.spacedBy(4.dp),
        verticalItemSpacing = 4.dp,
        contentPadding = PaddingValues(all = 4.dp),
        state = lazyListState
    ) {
        items(list) {
            PhotosItem(photosModel = it)
        }
        if (loading) {
            item {
                CircularProgressIndicator(
                    modifier = Modifier.width(64.dp),
                    color = MaterialTheme.colorScheme.secondary
                )
            }
        }
    }
}

修复后效果

  • 触发加载时,原有列表数据会被保留,LazyVerticalStaggeredGrid正常显示已有内容,底部同时显示加载指示器。
  • 加载成功后,新数据会自动追加到列表中,Grid无缝更新展示新内容。

内容的提问来源于stack exchange,提问作者Dnyaneshwar Patil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 17:14:55