Stylianos Gakis
04/09/2024, 12:54 PMText("HHHHHH")
. But then have it somehow not render itself on the screen, so nothing is drawn at that area. But after that I still want to draw something in its place, with the exact same size?
More in thread:Box(Modifier.padding(horizontal = 16.dp)) {
Text(
"HHHHHHHHHHHHHHHHHH",
modifier = Modifier
.layout { measurable, constraints ->
val placeable = measurable.measure(constraints)
layout(placeable.width, placeable.height) {}
},
)
Box(
Modifier
.matchParentSize()
.debugBorder()
.placeholder(true, highlight = PlaceholderHighlight.shimmer()),
)
}
I take as much space as “HHHHHHHHHHHHHHHHHH”, and then I draw the second item in this box by doing matchParentSize()
Text(
"HHHHHH",
modifier = Modifier
.layout { measurable, constraints ->
val placeable = measurable.measure(constraints)
layout(placeable.width, placeable.height) {}
}
//.alpha(0f) or this
.drawBehind { ... }
.placeholder(true, highlight = PlaceholderHighlight.shimmer()),
)
But after I do the layout
to not place anything there, (or even with an alpha(0f)) to hide everything at that point and then still be able to draw on it. But I can’t get it working so far at leastZach Klippenstein (he/him) [MOD]
04/09/2024, 1:09 PMStylianos Gakis
04/09/2024, 1:21 PM@Composable
fun LayoutWithoutRendering(modifier: Modifier = Modifier, content: @Composable () -> Unit) {
Layout(content = content, modifier = modifier) { measurables, constraints ->
val placeable = measurables.first().measure(constraints)
layout(placeable.width, placeable.height) {}
}
}
And with call-site:
LayoutWithoutRender(
modifier = Modifier
.padding(horizontal = 16.dp)
.drawBehind { drawRect(Color.Red) }
) {
Text(text = "HHHHHHHHHHHHHHHHHH")
}
And this does exactly what I was looking for actually. Since the modifier is added on the layout itself, I just don’t place the content. but measure it and adjust the layout size to it.
The only thing this does wrong is that if you write more than one thing in the content block it will just not pick that up, but that should be fine. If I am not giving a BoxScope or ColumnScope or whatever they should not pass more than one anywayLayout(content = { Box { content() } }, modifier = modifier) { measurables, constraints ->
To wrap it all in a box, and have more than one item be a bit of undefined behavior, or even pass BoxScope to it so it’s more “defined” 🤷Albert Chang
04/09/2024, 1:27 PMLayoutModifierNode
hides the child, and the other DrawModifierNode
draws the placeholder. The reason we use two nodes is that the LayoutModifierNode
need to be applied after the DrawModifierNode
, which I don’t think is possible with a single modifier node.Stylianos Gakis
04/09/2024, 1:30 PMZach Klippenstein (he/him) [MOD]
04/09/2024, 1:38 PMAlbert Chang
04/09/2024, 1:46 PMStylianos Gakis
04/09/2024, 1:49 PMAlbert Chang
04/09/2024, 1:49 PMI don’t understand why you’d need two modifier nodesBecause we wanted something like this:
Modifier
.drawWithContent {
drawContent()
...
}
.layout { measurable, constraints ->
val placeable = measurable.measure(constraints)
layout(placeable.width, placeable.height) {
placeable.placeWithLayer(0, 0) {
alpha = someAlpha
}
}
}
I know I can use drawContext.canvas.withSaveLayer(...) { drawContent() }
but I'm not sure if it's as efficient.Ruckus
04/09/2024, 2:44 PMBegs for a better name
Perhaps
Holdout
?Stylianos Gakis
04/09/2024, 2:45 PMRuckus
04/09/2024, 2:49 PMReserveSpace
?