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

Jetpack Compose如何将List<T>标记为Stable避免不必要重组

Compose 中List类型参数引发不必要重组的解决方案

重组触发条件

@Composable 函数会在以下场景触发重组:

  • 任意参数发生变更
  • 任意参数未被标记为@Stable/@Immutable

问题说明

当传入items: List<Int>作为参数时,即便List本身是不可修改的,Compose仍会始终触发重组——原因是List为未添加@Stable注解的接口。因此所有接收List<T>类型参数的Composable函数都会触发重组,无法享受智能重组优化。

优化方案

要将List<T>标记为稳定类型,让编译器识别其不可变属性,避免因该参数触发不必要的重组,目前可行的方案是对List进行包装,示例定义如下:

@Immutable data class ImmutableList<T>(val items: List<T>)

问题复现代码

以下演示场景中,当Child1触发Parent重组时,传入相同List的Child2也会被无意义重组:

class TestActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeBasicsTheme {
                Parent()
            }
        }
    }
}

@Composable
fun Parent() {
    Log.d("Test", "Parent Draw")
    val state = remember { mutableStateOf(false) }
    val items = remember { listOf(1, 2, 3) }

    Column {
        // 点击触发Parent重组
        Child1(value = state.value,
            onClick = { state.value = !state.value })

        Child2(items)
    }
}

@Composable
fun Child1(
    value: Boolean,
    onClick: () -> Unit
) {
    Log.d("Test", "Child1 Draw")
    Text(
        "Child1 ($value): 点击触发Parent重组",
        modifier = Modifier
            .clickable { onClick() }
            .padding(8.dp)
    )
}

@Composable
fun Child2(items: List<Int>) {
    Log.d("Test", "Child2 Draw")
    Text(
        "Child 2 (${items.size})",
        modifier = Modifier
            .padding(8.dp)
    )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 06:21:02