Building flexible Rows & Columns using Jetpack Compose

Michael McCormick
3 min readJun 11, 2021

--

Like myself, many Android developers will at some point need to build a Column or Row whose children have flexible sizes. An example of this can be seen in the above image, the users image has a fixed width, the timestamp will wrap the width of the text, and the name/message shown in the centre will expand to fill the available space.

So how do we create flexible layouts like this using Jetpack Compose? If you’ve already done some research, you may have come across the FlexColumn/FlexRow composables, however, as of version 0.1.0-dev15 these have been removed. Instead, we utilise the weight modifier!

Weight modifier

fun Modifier.weight(weight: Float, fill: Boolean = true)

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. When fill is true, the element will be forced to occupy the whole width allocated to it. Otherwise, the element is allowed to be smaller - this will result in Row being smaller, as the unused allocated width will not be redistributed to other siblings.

Note: the weight modifier is only available inside of a ColumnScope or RowScope, meaning that it can only be used directly within a Column or Row.

Let’s take a look at some example usages

Examples

All of the following examples show usages of the weight modifier in a Row, but each will work the same way when applied to a Column (expanding vertically rather than horizontally).

Example A

In this example Child 1 has a fixed width, Child 3 will wrap its contents, and Child 2 expands to fill the available space between them.

Row {
Child1(
modifier = Modifier.width(100.dp),
)
Child2(
modifier = Modifier.weight(1f),
)
Child3()
}

Example B

In this example Child 1 has a fixed width, Child 2 and Child 3 expand to fill half of the available space each.

Row {
Child1(
modifier = Modifier.width(80.dp),
)
Child2(
modifier = Modifier.weight(1f),
)
Child3(
modifier = Modifier.weight(1f),
)
}

Example C

In this example Child 3 has a fixed width, Child 1 expands to fill 2/3 of the available space, Child 2 expands to fill 1/3 of the remaining space.

Row {
Child1(
modifier = Modifier.weight(2f),
)
Child2(
modifier = Modifier.weight(1f),
)
Child3(
modifier = Modifier.width(80.dp),
)
}

Example D

In this example the widths/weights are the same as in Example C, however, Child 2 is not forced to fill all of the available space.

Row {
Child1(
modifier = Modifier.weight(2f),
)
Child2(
modifier = Modifier.weight(1f, fill = false),
)
Child3(
modifier = Modifier.width(80.dp),
)
}

Code

Thanks for reading! The code for all examples provided can be found here: https://github.com/MichaelM97/Jetpack-Compose-Flexible-Layouts

--

--