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
相关产品推荐
相关产品推荐

