Mastering FlowRow & FlowColumn in Jetpack Compose for Responsive UI

This article explores Jetpack Compose's FlowLayout components, comparing them with lazy layouts, demonstrating basic and advanced usage—including item alignment, weight handling, and grid-like arrangements—to build responsive Android interfaces that adapt gracefully to varying screen sizes.

AndroidPub
AndroidPub
AndroidPub
Mastering FlowRow & FlowColumn in Jetpack Compose for Responsive UI

FlowLayout vs LazyLayout

When choosing between lazy layouts ( LazyRow / LazyColumn) and flow layouts ( FlowRow / FlowColumn), consider the number of items and the desired behavior. Lazy layouts render only visible items, making them ideal for large or potentially infinite lists that scroll vertically or horizontally, offering high performance and low memory usage.

Flow layouts, on the other hand, compose all children at once and automatically wrap items to the next line or column when space runs out. They are best suited for a small, fixed set of items—such as chips or filter collections—where wrapping is required instead of scrolling.

For a hybrid approach that combines both lazy loading and flow behavior, see the article on Lazy Grids referenced in the source.

Basic Usage

To use FlowRow or FlowColumn, simply create the composable and place child items inside. The children follow standard flow rules and wrap 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")
    }
}
FlowRow example showing automatic line wrapping
FlowRow example showing automatic line wrapping

The example demonstrates how items automatically move to the next line when the current line lacks sufficient space, adapting to both narrow and wide screens.

Handling Varying Item Sizes and Weights

FlowRow

and FlowColumn seamlessly handle items of different sizes; the row 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
            )
        }
    }
}
FlowRow with varying item sizes and weights
FlowRow with varying item sizes and weights

Flow layouts also support item weights via Modifier.weight. Unlike Row, the weight is calculated only among items in the same line, allowing precise control of space distribution within each wrapped line.

@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))
            }
        }
    }
}

Advanced Fine‑Tuning of Flow Layouts

Beyond basic wrapping, FlowLayout offers parameters to control spacing, alignment, and the maximum number of items per line or column.

Main axis arrangement : Use horizontalArrangement for FlowRow or verticalArrangement for FlowColumn to set spacing, start, end, center, or space‑between distribution.

Cross axis alignment : Items in FlowRow align vertically by default (top), while FlowColumn aligns horizontally (start). Override with Modifier.align() for individual items.

Maximum items per line/column : maxItemsInEachRow or maxItemsInEachColumn limits how many children appear before wrapping, enabling a grid‑like appearance without writing a full grid composable.

Advanced FlowLayout configuration
Advanced FlowLayout configuration

Conclusion

FlowLayout is a key tool for building responsive Android UIs, allowing content to wrap instead of scroll when the number of items is small and fixed. By understanding when to prefer FlowLayout over lazy layouts and leveraging weight, spacing, and max‑item parameters, developers can create clean, adaptable interfaces with minimal code.

References

Android official documentation: https://developer.android.com/

“Lazy Grids in Jetpack Compose” article: https://oguzhanaslan.medium.com/lazygrids-in-jetpack-compose-123456789

AndroidJetpack Composeresponsive UIComposableFlowLayoutLazyLayout
AndroidPub
Written by

AndroidPub

Senior Android Developer & Interviewer, regularly sharing original tech articles, learning resources, and practical interview guides. Welcome to follow and contribute!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.