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

Android Jetpack Compose LazyColumn多选重组问题求解

Android Jetpack Compose 多选功能的重组优化方案探讨

我在Android Jetpack Compose中实现多选功能时碰到了重组问题,目前已有可行方案,但对类的@Stable注解使用存在困惑,希望能获取其他实现思路。

前提条件

  • 使用外部Java库中的模型类作为LazyColumn的列表项;
  • LazyColumn需实现多选功能,并通过rememberSaveable保存选中项状态。

现有实现

为实现多选,我编写了Selector类用于获取可存入Bundle的键:

class Selector<I, K> (
    private val selectable: SnapshotStateList<I>,
    private val keyProvider: (I) -> (K)
)

我将选中状态存储在映射中,关联键与选中状态:

private val _selectedStates = ArrayMap<K, WeakReference<MutableState<Boolean>>>()
val selectedState: (I) -> State<Boolean>
    get() = state@{ item ->
        val key = keyProvider(item)
        val currentState = _selectedStates[key]?.get()
        return@state if (currentState != null) {
            currentState
        } else {
            val state = mutableStateOf(_selection.containsKey(key))
            _selectedStates[key] = WeakReference(state)
            state
        }
    }

在LazyColumn的items块中读取状态并修改项背景:

LazyColumn(
    modifier = Modifier.fillMaxSize(),
    contentPadding = contentPadding,
    state = listState
) {
    items(
        items = items,
        key = { item -> item.hashCode() }
    ) { item ->
        val selectedState = selector.selectedState(item)
        val isSelected = { selectedState.value }
        /* 读取isSelected()的相关代码 */
    }
}

遇到的重组问题

当contentPadding变化时(比如滚动Scaffold的TopAppBar导致contentPadding改变),由于_selectedStates并非稳定属性,LazyColumn的所有项都会触发不必要的重组。

已尝试的方案

  1. 可行但存疑的方案:给Selector类添加@Stable注解,可避免不必要的重组,但我觉得这种方式略显取巧;
  2. 改用SnapshotStateMap:将映射改为SnapshotStateMap(mutableStateMapOf<>())后,首次加载列表项时会触发不必要的重组——加载选中状态后存入映射,映射变化会导致LazyColumn的items块重新加载,且remember { selector.selectedState }无效果;
  3. 不存储选中状态:仅提供isSelected函数,此时任何选中状态变化都会导致所有项重组:
val isSelected: (I) -> Boolean = { item -> _selection.contains(keyProvider(item)) }

请问是否存在更稳定的方案,用于保存每个列表项的独立选中状态?


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 08:57:39