android-jetpack-compose

How to set Row's height as wrap_content?


I want to have such a UI structure with Jetpack Compose:

Here is my code:


@Composable
fun ColumnTest() {
    Box(
        modifier = Modifier
            .fillMaxWidth()
            .height(300.dp)
    ) {
        Row(
            modifier = Modifier
                .background(Color.Cyan)
                .padding(horizontal = 12.dp)
                .wrapContentHeight(align = Alignment.Top)
        ) {
            Column(
                modifier = Modifier
                    .width(40.dp)
                    .fillMaxHeight()
                    .background(color = Color.Green)
            ) {

            }

            Spacer(
                modifier = Modifier
                    .width(10.dp)
                    .fillMaxHeight()
                    .background(Color.Yellow)
            )

            Column(
                modifier = Modifier
                    .background(Color.Magenta)
                    .fillMaxWidth()
            ) {
                ChatText("Label 1")
                ChatText("Label 2")
                ChatText("Label 3")
                ChatText("Label 4")
                ChatText("Label 5")
            }
        }
    }
}

With this code, the UI looks like: enter image description here

So for the Row, its expected height should be exactly as tall as the Column_2 (the one with 5 labels in it), but the Row takes up all of the available height the parent (i.e.: the Box) owns.

Question: how to make the Row's height as wrap_content?

Update:

Thanks for @benedict santiago's help, now with the code below, it is able to set the Row as wrap_content.

@Composable
fun ColumnTest() {
    Box(
        modifier = Modifier
            .fillMaxWidth()
            .height(300.dp)
    ) {
        Row(
            modifier = Modifier
                .background(Color.Cyan)
                .padding(horizontal = 12.dp)
                .wrapContentHeight(align = Alignment.Top) // Row wraps its content
        ) {
            Column(
                modifier = Modifier
                    .width(40.dp)
                    .background(Color.Green)
            ) {
                // Put something inside if you want visible height
                Text("A")
            }

            Spacer(
                modifier = Modifier
                    .width(10.dp)
                    .background(Color.Yellow)
            )

            Column(
                modifier = Modifier
                    .background(Color.Magenta)
                    .fillMaxWidth() // Fill remaining horizontal space
            ) {
                ChatText("Label 1")
                ChatText("Label 2")
                ChatText("Label 3")
                ChatText("Label 4")
                ChatText("Label 5")
            }
        }
    }
}

It looks like: enter image description here

However, here comes the 2nd question: how to make the Column_1 (the green section) match parent's height? I.e.: how to make its height exactly the same with Column_2?

P.S.: I can do it with mutableState and onGloballyPositioned, which is getting the height of the Column_2 first, then set the height onto Column_1, but I am asking if there is any other solution more straightforward.


Solution

  • What you want to use are intrinsic measurements like this:

    Row(
        modifier = Modifier
            .background(Color.Cyan)
            .padding(horizontal = 12.dp)
            .height(IntrinsicSize.Min)
    ) {
        //... use child Composables with Modifier.fillMaxHeight()
    }
    

    Then, the Row will be as high as the highest child Composable, while all other child Composables fill the height of the Row.