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

Jetpack Compose列表更新时避免不必要重组的优化方案

优化Jetpack Compose中MultiSelectGroup的重组效率

核心问题分析

你遇到的全量重组问题,本质是因为List属于不稳定数据类型:每次点击后生成新的List实例赋值给selectedItems,Compose会认为currentSelections整体发生变化,进而触发所有依赖该参数的FilterChip重组。

解决方案

1. 用mutableStateListOf替代mutableStateOf存储选中项

mutableStateListOf是Compose提供的可观察列表,它会跟踪元素的增删操作而非生成新实例,让Compose能精准感知局部变化:

val allItems = remember { (1..6).map {"$it"} }

// 替换原有的mutableStateOf(emptyList())
val selectedItems = remember { mutableStateListOf<String>() }

MultiSelectGroup(
    items = allItems,
    currentSelections = selectedItems,
    onSelectionsChanged = { newSelections ->
        selectedItems.clear()
        selectedItems.addAll(newSelections)
    },
)

2. 为FilterChip添加唯一Key并优化选中状态判断

给每个FilterChip绑定唯一key,帮助Compose识别子项身份;同时将选中列表转为Set缓存,提升contains查询效率:

@OptIn(ExperimentalLayoutApi::class, ExperimentalMaterial3Api::class)
@Composable
fun MultiSelectGroup(
    items: List<String>,
    currentSelections: List<String>,
    onSelectionsChanged: (List<String>) -> Unit,
) {
    // 缓存选中项为Set,仅在currentSelections变化时重新生成
    val selectedSet = remember(currentSelections) { currentSelections.toSet() }

    FlowRow {
        items.forEach { item ->
            FilterChip(
                // 绑定唯一Key,避免无意义重组
                key = item,
                label = { Text(item) },
                // 用Set的contains提升查询效率
                selected = selectedSet.contains(item),
                onClick = {
                    val newSelectedChips = currentSelections.toMutableList().apply {
                        if (contains(item)) {
                            remove(item)
                        } else {
                            add(item)
                        }
                    }
                    onSelectionsChanged(newSelectedChips)
                },
            )
        }
    }
}

3. 可选:直接操作MutableStateList简化逻辑

如果组件无需兼容外部List类型,可以直接接收MutableStateList,省去回调转换步骤:

@OptIn(ExperimentalLayoutApi::class, ExperimentalMaterial3Api::class)
@Composable
fun MultiSelectGroup(
    items: List<String>,
    selectedItems: MutableList<String>,
) {
    val selectedSet = remember(selectedItems) { selectedItems.toSet() }

    FlowRow {
        items.forEach { item ->
            FilterChip(
                key = item,
                label = { Text(item) },
                selected = selectedSet.contains(item),
                onClick = {
                    if (selectedItems.contains(item)) {
                        selectedItems.remove(item)
                    } else {
                        selectedItems.add(item)
                    }
                },
            )
        }
    }
}

// 调用处简化为
MultiSelectGroup(
    items = allItems,
    selectedItems = selectedItems,
)

优化效果

完成上述修改后,点击某个FilterChip时,仅有该Chip会因selected状态变化而重组,其他未改变状态的Chip不会触发不必要的重组,大幅提升组件性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 02:46:23