@Composable函数会被重新组合:
- 如果其中一个参数被更改,或者
- 如果其中一个参数不是@Stable/@Immutable
当将items: List<Int>
作为参数传递时,compose始终会进行重新组合,无论List
是否是不可变的并且无法更改。(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 {
// click forces recomposition of 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): Click to recompose 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)
)
}
items
参数的可组合项长什么样,您如何从另一个可组合项调用它以及导致顶层函数重新组合的原因是什么。 - Phil Dukhov