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

LazyColumn加载ViewModel数据时切换日期触发数组越界崩溃

Jetpack Compose LazyColumn切换日期时索引越界崩溃问题

问题说明

使用Jetpack Compose的LazyColumn展示按选中日期筛选的药品数据,切换日期导致列表项数量变化时,应用抛出IndexOutOfBoundException崩溃。固定日期时功能正常,已确认数据能正确更新,改用普通可滚动Column或仅展示列表长度时无异常,问题锁定在LazyColumn的重组逻辑上。

相关代码

从ViewModel获取数据

val allMedicines by viewModel.getMedicineByTime(selectedDateMillis).collectAsStateWithLifecycle(initialValue = emptyList())

初始LazyColumn实现

if (allMedicines.isEmpty()) {
    AnimateLottieRaw(resId = R.raw.empty_box, modifier = Modifier.size(200.dp))
    Text(
        text = "No Medicines scheduled for today\ntry adding some using the + button below",
        modifier = Modifier.fillMaxSize(),
        fontFamily = dmSansFont,
        textAlign = TextAlign.Center,
    )
} else {
    LazyColumn(modifier = Modifier.fillMaxSize()) {
        items(allMedicines) { medicine ->
            MedicineCard(medicine = medicine) {
                onEvent(ClickEvents.EditMedicine(it))
            }
        }
    }
}

尝试过的替代实现(问题依旧)

LazyColumn(modifier = Modifier.fillMaxSize()) {
     items(allMedicines.size) { pos ->
         val medicine = allMedicines[pos]
         MedicineCard(medicine = medicine) {
             onEvent(ClickEvents.EditMedicine(it))
         }
     }
}

错误日志摘要

java.lang.IndexOutOfBoundsException: 索引: [具体索引值], 大小: [当前列表长度]
at androidx.compose.foundation.lazy.LazyListItemProviderKt.getLazyListItemProvider(LazyListItemProvider.kt:81)
at androidx.compose.foundation.lazy.LazyListStateKt$items$3$1.invoke(LazyListState.kt:1264)
at androidx.compose.foundation.lazy.LazyListStateKt$items$3$1.invoke(LazyListState.kt:1261)
...(后续调用栈略)

排查思路与解决方案

  • 确保数据类的稳定性:检查Medicine是否为data class,且所有属性均为稳定类型(如基本类型、String、标记@Stable/@Immutable的自定义类)。不稳定的数据类会导致Compose无法正确追踪列表项变化,引发索引异常。
  • 使用带唯一键的items重载:给LazyColumn的items指定唯一键(比如药品ID),让Compose能精准识别列表项的增删,避免索引匹配错误:
items(allMedicines, key = { medicine -> medicine.id }) { medicine ->
    MedicineCard(medicine = medicine) {
        onEvent(ClickEvents.EditMedicine(it))
    }
}
  • 验证数据更新的原子性:确保ViewModel中getMedicineByTime返回的Flow在查询数据库时是原子操作,避免在重组过程中列表被部分更新,导致LazyColumn读取到不一致的列表状态。
  • 升级Compose版本:部分旧版本的Compose LazyColumn存在索引越界的已知bug,建议升级到最新稳定版(如androidx.compose.foundation:foundation:1.6.0及以上)。
  • 检查子组件状态:确认MedicineCard内部没有持有与传入参数无关的状态,避免重组时旧状态与新数据冲突引发异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 17:03:18