I was given a design to basically create a Contain...
# compose
c
I was given a design to basically create a Container (will try to accomplish this via "slot api") that can accept any component but the background of the container should be 50% of the child that it's hosting. So the container still has to be big enough to fit the child... it's just that they want to create this "offset" effect with the color. Brute force solution in thread:
Copy code
@Composable
fun OffsetBackgroundContainer(
content: @Composable BoxScope.() -> Unit
){
    Box {
        Box(Modifier.background(Color.Green).height(100.dp))
        content()
    }
}
It gets me that offset effect that works sometimes, but I'm not sure how I would get the content height and set it to the modifier to replace the 100.dp
s
Maybe wrap the content with a
Box
and use
Modifier.onSizeChanged
on that box to get the height
a
Copy code
@Preview
@Composable
fun Boxy() {
    Box {
        Box(
            Modifier
                .matchParentSize()
                .wrapContentHeight(<http://Alignment.Top|Alignment.Top>)
                .fillMaxHeight(0.5f)
                .background(Color.Green)
        )

        Card(Modifier.padding(horizontal = 16.dp).height(150.dp)) {
            Text("Hello, world", Modifier.padding(16.dp))
        }
    }
}
👍 1
The key is the
.matchParentSize()
modifier available in
BoxScope
. It makes the green part measure last based on the size of the rest of the box's content. From there it's just a matter of sizing it to half the max height and aligning it within the space.
👍 2
c
I lose internet access for the past few hours, but I tried to create something like what Ashar said and came up with something like this
Copy code
Box() {
    var sizeOfContent by remember { mutableStateOf(IntSize(0, 0)) }

    Box(
        Modifier.background(Color.Blue)
            .height(with(LocalDensity.current) { (sizeOfContent.height).toDp().times(0.50F) })
            .fillMaxWidth()
    )

    Column(modifier.onSizeChanged { sizeOfContent = it }) {
and it actually works pretty well. I will try the solution from Adam Powell now though.
a
The problem with using a height modifier influenced by onSizeChanged like that is that it can't converge in a single frame. It requires recomposing the size modifier on another frame with the new value.
🤔 1
c
Not sure I quite understand... but I think it basically means that the height will always technically be 1 "frame" behind? Or does it mean that my code will recompose 1 extra time unnecessarily? Just tried your solution... that works super well. What a nice string of modifiers to accomplish that. I would have never gotten that on my own. 😄
a
It means both, the height will always be one frame behind and your code will recompose one extra time after every frame when the size changes, producing another unnecessary subsequent layout after that to follow the height.
c
Interesting. I guess there's no good way to "catch" these sorts of things right? Except to be aware of what triggers what?