Open
Description
If in a custom Layout
implementation, a node gets measured/placed during one composition and then not measured/placed on a subsequent one, it still participates in draw.
@Test
fun conditionalPlacement() = runTest {
runMosaicTest {
setContent {
Layout(
modifier = Modifier.width(LocalTerminal.current.size.width),
content = {
Text("Hello")
Text("World")
}
) { measurables, constraints ->
val helloPlaceable = measurables[0].measure(constraints)
val worldPlaceable = if (constraints.maxWidth >= 10) {
measurables[1].measure(constraints)
} else {
null
}
layout(5, 1) {
helloPlaceable.place(0, 0)
worldPlaceable?.place(0, 0)
}
}
}
assertThat(awaitSnapshot()).isEqualTo("World")
terminalState.update { copy(size = IntSize(5, 1)) }
assertThat(awaitSnapshot()).isEqualTo("Hello")
}
}
Not entirely sure if this is allowed per the Layout
contract? I don't believe this is the current behavior of Compose UI. My test:
@Preview
@Composable
fun ConditionalPlacementTest() {
var redSize by remember { mutableStateOf(100.dp) }
LaunchedEffect(Unit) {
while (true) {
delay(3000)
redSize = if (redSize == 100.dp) 300.dp else 100.dp
}
}
Layout(
content = {
Box(modifier = Modifier.size(redSize).background(Color.Red))
Box(modifier = Modifier.size(100.dp).background(Color.Green))
}
) { measurables, constraints ->
val redPlaceable = measurables[0].measure(constraints)
val greenPlaceable = if (redPlaceable.width < 300) {
measurables[1].measure(constraints)
} else {
null
}
layout(redPlaceable.width, redPlaceable.height) {
redPlaceable.place(0, 0)
greenPlaceable?.place(0, 0)
}
}
}