androidlayoutandroid-jetpack-composeandroid-jetpack

Android Compose - how to match the height of composables side-by-side centered in a Box


I have 2 composables centered vertically in a Row, centered in a Box. The left side of the box is generated, an can be any height.

The problem is that the right side height is never stretched to the same height and the left side, so the TextButton is not the at the bottom of that side.

In case I make my Column fillMaxHeight(), then the whole Row is stretched to max screen size and under the generated content there is a space.

In case I use Spacer with a weight(1f), the whole row is stretched to the full height of the screen (Box), and the same problem happens as by using fillMaxHeight() for the Column

I want my Column on the right side to have the height of the Box on the left side (or if the left side is smaller then based on the right side wrapped content size) and this all centered vertically in the Box that wraps Row

Box (
    Modifier.weight(contentWeight).fillMaxWidth(),
    contentAlignment = Alignment.Center
){
    Row(
        modifier = Modifier.fillMaxWidth()
    ) {
        Box(modifier = Modifier.weight(1f)) {
            // a dynamically generated layout with non fixed height
        }
        Column(
            modifier = Modifier
                .fillMaxWidth(),
                .weight(1f),
            Arrangement.SpaceBetween
        ) {
            Text( text = ....)
            TextButton ( ...){
                Text (text = ...)
            }
        }
    }
}


Solution

  • You can assign IntrinsicSize.Min to your Row so that it matches the height of its smallest child Composable:

    Row(
        modifier = Modifier
            .fillMaxWidth()
            .height(IntrinsicSize.Min)
    ) {
        //...
    }
    

    Then, you can use fillMaxHeight on your Column without pushing the parent Row to full height:

    Column(
        modifier = Modifier
            .fillMaxWidth()
            .fillMaxHeight(),
        Arrangement.SpaceBetween
    ) {
        //...
    }
    

    Output:

    Screenshot