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

Jetpack Compose LazyVerticalGrid删除项后出现幽灵项点击错位问题

Jetpack Compose LazyVerticalGrid 删除项后索引错乱问题

刚接触Jetpack Compose,用Firestore获取的列表填充LazyVerticalGrid,删除某一项后视图已经更新,该项不再显示,但点击原删除位置的新项时,日志里还是会出现已删除项的引用;点下一项时选中的却是前一项,像是有“幽灵”残留,导致索引错乱。


相关代码

BrandViewModel

val brands = storageService.brands

StorageService

val brands: Flow<List<Brand>>

StorageServiceImpl

override val brands: Flow<List<Brand>>
    get() = auth.currentUser.flatMapLatest { user ->
        currentBrandCollection(user.id).snapshots().map { snapshot -> snapshot.toObjects() }
    }

Brand Screen

val brands by viewModel.brands.collectAsStateWithLifecycle(initialValue = emptyList())
..........

LazyVerticalGrid(
    state = listGridState,
    modifier = Modifier
        .padding(vertical = 4.dp)
        .padding(horizontal = 4.dp)
        .background(MaterialTheme.colorScheme.background)
        .padding(contentPadding),
    columns = GridCells.Adaptive(minSize = 124.dp),
) {
    itemsIndexed(brands) { index, brandItem ->
    ..........
}

问题场景

  • 初始列表:显示包含Ferrarelle、General等品牌的卡片列表
  • 选中项卡片:点击Ferrarelle卡片,正常触发选中逻辑
  • 删除项:删除Ferrarelle卡片后,视图中该卡片消失,后续卡片上移填补位置
  • 点击异常:点击原本Ferrarelle位置的General卡片,日志中却显示选中了已删除的Ferrarelle;点击下一个卡片时,实际选中的是前一个卡片

解决方案

问题根源是LazyVerticalGrid默认依赖项的位置索引进行组件复用,当列表项删除后,后续项的索引发生变化,但Compose仍可能复用之前的组件状态,导致索引与实际数据不匹配。

解决核心是给每个列表项指定唯一且稳定的key,让Compose能准确识别每个项,而非依赖位置索引:

方式1:替换为带key的items函数(推荐)

如果不需要索引,直接用items函数并传入项的唯一标识作为key:

LazyVerticalGrid(
    // 保留原有参数
) {
    items(
        items = brands,
        key = { brand -> brand.id } // 替换为Brand类中唯一标识字段,比如Firestore文档ID
    ) { brandItem ->
        // 你的卡片布局逻辑
        // 点击事件直接使用brandItem,不要依赖索引
    }
}

方式2:带key的itemsIndexed重载

如果确实需要使用索引,用带key参数的itemsIndexed:

LazyVerticalGrid(
    // 保留原有参数
) {
    itemsIndexed(
        items = brands,
        key = { index, brand -> brand.id } // 同样传入唯一标识
    ) { index, brandItem ->
        // 卡片布局逻辑
    }
}

额外注意

  • 确保Brand类的id是唯一且稳定的(比如Firestore自动生成的文档ID),不要使用临时生成的标识
  • 点击事件中优先使用brandItem本身获取数据,避免直接通过index从列表中取值,防止索引错乱

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 19:33:23