How can I make all cells of a Row have the width of the widest one?

Issue

I am making a "ToggleGroup" with Jetpack-Compose, using essentially a Row into which I print Text. I manage to make it work if I tune the width manually (.width(70.dp) in the code below), but I would like it to automatically do that.

I essentially want this:

enter image description here

But without manually adding .width(70.dp), I get this:

enter image description here

My current (tuned) code is the following:

Row(
    horizontalArrangement = Arrangement.End,
) {
    options.forEach { option ->
        val isSelected = option == selectedOption
        val textColor = if (isSelected) Color.White else MaterialTheme.colors.primary
        val backgroundColor = if (isSelected) Color.Gray else Color.White
        Row(
            horizontalArrangement = Arrangement.Center,
            modifier = Modifier
                .padding(
                    vertical = 6.dp, horizontal = 1.dp
                )
                .width(70.dp)
                .background(backgroundColor)
                .clickable { onSelectionChanged(option) }
        ) {
            Text(
                text = option,
                color = textColor,
                modifier = Modifier.padding(14.dp),
            )
        }
    }
}

It feels similar to this question, but somehow it’s different because I use Row and the question uses Column (or at least I did not manage to use Intrinsics correctly).

How could I do that?

Solution

Changes required.

1. On the parent Row, use Modifier.width(IntrinsicSize.Min)

(min|max)IntrinsicWidth: Given this height, what’s the minimum/maximum width you can paint your content properly?

Source – Docs

2. Use Modifier.weight(1F) on all children.

Size the element’s width proportional to its weight relative to other weighted sibling elements in the Row.

The parent will divide the horizontal space remaining after measuring unweighted child elements and distribute it according to this weight.

Source – Docs

3. Use Modifier.width(IntrinsicSize.Max) on all children.

This ensures the Text inside the children composables are not wrapped.

(You can verify this by removing the modifier and adding long text)

Screenshot

Sample code

@Composable
fun AutoWidthRow() {
    val items = listOf("Item 1", "Item 2", "Item 300")
    Row(
        horizontalArrangement = Arrangement.End,
        modifier = Modifier.width(IntrinsicSize.Min),
    ) {
        items.forEach { option ->
            Row(
                horizontalArrangement = Arrangement.Center,
                modifier = Modifier
                    .padding(
                        vertical = 6.dp, horizontal = 1.dp
                    )
                    .width(IntrinsicSize.Max) // Removing this will wrap the text
                    .weight(1F)
                    .background(Color.Black)
            ) {
                Text(
                    text = option,
                    color = Color.White,
                    modifier = Modifier
                        .padding(14.dp),
                )
            }
        }
    }
}

Answered By – Abhimanyu

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published