It’s a feature of Compose about scoping and smart recomposition. You can check my detailed answer here.
What really makes your whole Composable to recompose is Column
having inline keyword.
@Composable
inline fun Column(
modifier: Modifier = Modifier,
verticalArrangement: Arrangement.Vertical = Arrangement.Top,
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
content: @Composable ColumnScope.() -> Unit
) {
val measurePolicy = columnMeasurePolicy(verticalArrangement, horizontalAlignment)
Layout(
content = { ColumnScopeInstance.content() },
measurePolicy = measurePolicy,
modifier = modifier
)
}
Let’s say you have a Composable sets background color initially at composition and changes at each recomposition which creates its own scope. Lambda without inline is considered a scope.
@Composable
fun RandomColorColumn(content: @Composable () -> Unit) {
Column(
modifier = Modifier
.padding(4.dp)
.shadow(1.dp, shape = CutCornerShape(topEnd = 8.dp))
.background(getRandomColor())
.padding(4.dp)
) {
content()
}
}
With
@Composable
fun App2() {
var text by mutableStateOf("Hello, World!")
RandomColorColumn {
TextField(text, onValueChange = { text = it })
Button(onClick = {
text = "Hello, Desktop!"
}) {
Text(text)
}
}
}
And one with Column
@Composable
fun App() {
var text by mutableStateOf("Hello, World!")
Column(modifier = Modifier.background(getRandomColor())) {
TextField(text, onValueChange = { text = it })
Button(onClick = {
text = "Hello, Desktop!"
}) {
Text(text)
}
}
}
Random color function
fun getRandomColor() = Color(
red = Random.nextInt(256),
green = Random.nextInt(256),
blue = Random.nextInt(256),
alpha = 255
)
You will see that Column background color will change every time you change text but not with App2()