Flow Layouts in Compose

O

OฤŸuzhan Aslan

Guest
0*WSVJqXQ6sExnM9nu

Photo by Kelly Sikkema on Unsplash

In the world of UI development, creating a responsive and adaptable user interface is paramount. Jetpack Compose, Androidโ€™s modern UI toolkit, offers a wide array of layout composables to help developers build dynamic and flexible designs. While standard layouts like Row and Column are great for linear arrangements, they can sometimes fall short when dealing with content that needs to adapt and wrap based on available space. This is where flow layouts come in.

FlowRow and FlowColumn, are composables that are similar to Row and Column but with a key difference: items automatically flow onto the next line when the container runs out of space. This behavior creates multiple rows or columns, allowing for more responsive designs where content isn't cut off if items are too large for one dimension. They are especially useful for creating UIs like a collection of chips or filters, where items need to wrap to the next line as screen space decreases.

In this blog post, weโ€™ll dive deep into the features of flow layouts, exploring how to control their arrangement, align individual items, and use weights to create responsive grid-like structures.

Choosing Between Lazy and Flow Layouts​


When deciding between a lazy layout (LazyRow/LazyColumn) and a flow layout (FlowRow/FlowColumn), the key factors to consider are the number of items you're displaying and the desired behavior.

Lazy Layouts are the go-to choice for displaying a large or potentially unbounded list of items that require scrolling. These layouts are highly performant because they only compose (render) the items that are currently visible on the screen, a concept known as โ€œlazy loadingโ€. This approach is ideal for lists or grids that scroll vertically (LazyColumn) or horizontally (LazyRow), as it conserves memory and prevents performance issues that would arise from rendering all items at once.

Flow Layouts, on the other hand, are best suited for a small, fixed number of items where you want them to automatically wrap to the next line or column when the containerโ€™s space is filled. Unlike lazy layouts, flow layouts compose all of their children at once. They are not designed for scrolling but rather for creating wrapping layouts where items flow naturally to the next line within a constrained space.

For a more detailed look at lazy layouts, you can refer to the official Android documentation. If you need the features of both lazy and flow layouts, you might consider using lazy grids. You can find more information about lazy grids in my blog post:

LazyGrids in Jetpack Compose

Basic Usage​


To use aFlowRow or FlowColumn, you simply create the composable and place your items inside it. The items will follow the standard flow layout rules, automatically wrapping to a new line when necessary. A typical example is a chip UI.

@Composable
fun FlowRowSimpleUsageExample() {
FlowRow(modifier = Modifier.padding(8.dp)) {
ChipItem("Price: High to Low")
ChipItem("Avg rating: 4+")
ChipItem("Free breakfast")
ChipItem("Free cancellation")
ChipItem("ยฃ50 pn")
}
}

This code results in a UI where the items automatically flow to the next row when there isnโ€™t enough space on the current one. The following visuals demonstrate how this flexible layout adapts to different screen sizes, specifically showing how the chips wrap on a narrow phone screen versus a wider screen where all items can fit on a single line.

1*DA8MuvpX2ERy0lmDOGlvHw.png

1*O_fU-cq6BS8jywrbZ-4rAA.png

Same Composable in two different screens.

Handling Different Sized Items and Item Weights​


FlowRow and FlowColumn are designed to handle items of varying sizes seamlessly, with items wrapping to the next line as needed. The row's height is determined by the tallest item, and individual items can be aligned within that space.

@Composable
fun FlowRowVaryingSizesExample() {
FlowRow(
modifier = Modifier
.fillMaxWidth()
.padding(12.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
val itemWeights = listOf(1f, 2f, 1.5f, 1f, 2.5f, 1.2f, 1.8f, 1.3f)
repeat(8) { i ->
Text(
text = "Item ${i + 1}",
modifier = Modifier
.height(48.dp)
.weight(itemWeights[i % itemWeights.size])
.clip(RoundedCornerShape(16.dp))
.background(Color.Blue)
.padding(8.dp),
color = Color.White
)
}
}
}
1*yRhIWxMXYOq4-pRVJsQZ6Q.png

1*MYDC2xwiOLMWVeBFGsLe3g.png

Varying sizes on views on FlowRow

In addition, a powerful feature of flow layouts is the use of item weights. This allows items to grow based on a specified factor and the available space on their specific line. Itโ€™s crucial to understand that in a FlowRow, a weight is based only on the other items within the same line, unlike a regular Row where it's based on all items in the Row.

For example, if a line in a FlowRow contains two items with weights of 0.5f and 0.5f, they will each take up half of the available width on that line. If a line has a single item with Modifier.fillMaxWidth(), it will take up the full width of the line.

You can combine Modifier.weight with maxItemsInEach to create a responsive, grid-like layout that adapts to a device's size, as shown below. This is useful for creating layouts with alternating item sizes.

@Composable
fun FlowRowWeighted(modifier: Modifier = Modifier) {
FlowRow(
modifier = Modifier.padding(4.dp),
horizontalArrangement = Arrangement.spacedBy(4.dp),
maxItemsInEachRow = 2
) {
val itemModifier = Modifier
.padding(4.dp)
.height(80.dp)
.clip(RoundedCornerShape(8.dp))
.background(Color.Blue)
repeat (6) { item ->
if ((item + 1) % 3 == 0) {
Spacer(modifier = itemModifier.fillMaxWidth())
} else {
Spacer(modifier = itemModifier.weight(0.5f))
}
}
}
}
1*V0iyhfveR_5aGJzUWr3TbA.png

1*etU3mISVfYtR8PJuuw4GBg.png

Beyond the Basics: Fine-Tuning Flow Layouts​


Flow layouts in Jetpack Compose go far beyond simply placing items side-by-side. With a few extra parameters, you can control exactly how your UI is spaced, aligned, and arranged.

The main axis is the direction items naturally flow: horizontal in a FlowRow and vertical in a FlowColumn. Along this axis, you can adjust how space is shared between items using horizontalArrangement (for FlowRow) or verticalArrangement (for FlowColumn). Whether you want everything packed toward the start, pushed to the end, centered, spaced evenly, or separated by a fixed gap, these settings give you the control you need.

The cross axis is the perpendicular directionโ€Šโ€”โ€Švertical in a FlowRow and horizontal in a FlowColumn. This controls how entire rows or columns sit within the container. By default, items start at the top in a FlowRow and at the start in a FlowColumn, but you can change that to suit your layout.

If one item needs to stand out or break alignment rules, Modifier.align() lets you position it differently from its neighbors. This is especially useful when items vary in height or width, or when you want a single element to be visually distinct.

Finally, you can control how many items appear in a single row or column using maxItemsInEachRow or maxItemsInEachColumn. The default is effectively unlimited, but setting a number like 3 instantly creates a neat, grid-like look. By combining these adjustments, you can go from a simple flow of items to a polished, precisely arranged interface without much extra code.

1*_JFo28x1jKbqsuuJQUF62Q.gif

1*bxluJRZBp_3Odwiz8Z-ANw.gif

Summary​


This blog post provides a comprehensive guide to using flow layouts in Jetpack Compose. Flow layouts are a crucial tool for building responsive UIs that adapt to various screen sizes by allowing content to wrap onto new lines. Weโ€™ve explored the key differences between flow layouts and lazy layouts, demonstrating that flow layouts are better suited for smaller, fixed-item UIs where wrapping is the desired behavior over scrolling.

We also covered the core features of flow layouts, including:

  • Basic usage with an example of a chip UI that adapts to different screen sizes.
  • The use of item weights to create dynamic and responsive grid-like structures.
  • Advanced parameters for controlling arrangement, alignment, and the maximum number of items per line, enabling fine-grained control over your layouts.

By understanding and utilizing these features, you can create more adaptable and visually appealing user interfaces in Jetpack Compose.

References​


Flow layouts in Compose | Android Developers

LinkedIn

Love you all.

Stay tune for upcoming blogs.

Take care.


stat



Flow Layouts in Compose was originally published in ProAndroidDev on Medium, where people are continuing the conversation by highlighting and responding to this story.

Continue reading...
 


Join ๐•‹๐•„๐•‹ on Telegram
Channel PREVIEW:
Back
Top