Understanding Flow Row/Column vs. Contextual Flow Row/Column in Jetpack Compose

Charles Raj Iruthayaraj
4 min readSep 26, 2024

--

Hello Buddy’s

Jetpack Compose offers several ways to arrange UI elements on the screen, and two notable ones are the Flow Row/Column and the Contextual Flow Row/Column. Both provide a flexible way to manage your layouts, especially when dealing with dynamic content. In this blog, we will explore the differences between these two approaches, how they work, and when to use them. We’ll also include an example of a scrollable layout using Flow Row/Column to demonstrate how they can adapt to more complex UI scenarios.

What Are Flow Row and Flow Column?

Flow Row and Flow Column in Jetpack Compose allow for flexible, adaptive layouts. When using a Flow Row, items are arranged horizontally, and if they exceed the width of the screen, they wrap onto the next line. Similarly, a Flow Column arranges items vertically and wraps items that exceed the column’s height.

These layouts are perfect for handling dynamic content where the size or number of elements is not predetermined, such as when working with lists of items or content that needs to fit into a flexible space.

Key Features of Flow Row/Column:

  • Flexibility: Items can wrap onto the next row or column if they exceed the available space.
  • Dynamic positioning: Automatically adjusts the layout based on the size and number of items.
  • Alignment options: Provides control over how items align within their rows or columns.

Example of Flow Row:

FlowRow (
modifier = Modifier
.padding(8.dp)
.fillMaxWidth()
.border(width = 1.dp, color = Color.Magenta, shape = RoundedCornerShape(16.dp))
,
horizontalArrangement = Arrangement.SpaceBetween,
verticalArrangement = Arrangement.Center
) {
itemList.forEach { item ->
SuggestionChip(
onClick = { /*TODO*/ },
label = { Text(text = item.text ?: "") },
modifier = Modifier
.width(item.width)
.height(70.dp)
.padding(10.dp)
)
}
}

In this example, the items will wrap to the next line if they don’t fit within the available width.

Contextual Flow Row/Column

The Contextual Flow Row/Column introduces an additional layer of customization by allowing developers to control item placement based on context, such as screen size or item attributes. While Flow Row/Column adapts based on available space, Contextual Flow layouts provide developers with more granular control, especially when specific layout requirements need to be met under varying conditions.

Key Features of Contextual Flow Row/Column:

  • Custom wrapping behavior: Developers can define how and when items should wrap based on specific conditions.
  • Condition-based layout: Adapts more effectively to changes in context, such as different device sizes or orientation changes.
  • Greater control over layout: More flexibility in customizing how items are arranged within the flow.

This layout is ideal when you need to manage more complex UI arrangements or when precise control over wrapping behavior is required.

Example of Contextual Flow Row:

ContextualFlowRow (
modifier = Modifier
.padding(8.dp)
.fillMaxWidth()
.border(width = 1.dp, color = Color.Magenta, shape = RoundedCornerShape(16.dp))
,
horizontalArrangement = Arrangement.SpaceBetween,
verticalArrangement = Arrangement.Center,
itemCount = itemList.count(),
overflow = ContextualFlowRowOverflow.Clip
) { it ->

val item = itemList[it]
SuggestionChip(
onClick = { /*TODO*/ },
label = { Text(text = item.text ?: "") },
modifier = Modifier
.width(item.width)
.height(70.dp)
.padding(10.dp)
)
}

In this case, the ContextualFlowRow allows you to limit the number of items per row, even if there is space for more, which can be useful when you want to maintain a specific design layout.

Comparison: Flow Row/Column vs. Contextual Flow Row/Column

Flexibility:

  • Flow Row/Column: Automatically wraps items based on available space.
  • Contextual Flow Row/Column: Provides more control over when and how items wrap.

Customization:

  • Flow Row/Column: Limited to managing spacing and alignment.
  • Contextual Flow Row/Column: Allows defining custom conditions for wrapping behavior.

Use Case:

  • Flow Row/Column: Best suited for simple, adaptive layouts.
  • Contextual Flow Row/Column: Ideal for more complex layouts that require additional control.

Screen-size Sensitivity:

  • Flow Row/Column: Offers basic adaptation based on available space.
  • Contextual Flow Row/Column: Can adapt based on specific screen sizes or content contexts.

Memory Usage and Loading Behavior:

  • Flow Row/Column: Takes up memory for all items simultaneously, even those not visible on the screen, which could increase memory usage for large data sets.
  • Contextual Flow Row/Column: More memory efficient, as it only takes up memory for the visible items on the screen, loading additional items as needed when they come into view.

Example with Scrollable Layout

In dynamic UIs, scrolling is often required, especially when displaying lists of items. Using FlowRow or FlowColumn within a scrollable container enables a flexible layout while ensuring all content is accessible.

Example: Scrollable Flow Row

val verticalScrollState = rememberScrollState(initial = 0) 

ContextualFlowRow (
modifier = Modifier
.padding(8.dp)
.fillMaxWidth()
.fillMaxHeight()
.border(width = 1.dp, color = Color.Magenta, shape = RoundedCornerShape(16.dp))
.verticalScroll(verticalScrollState)
,
horizontalArrangement = Arrangement.SpaceBetween,
verticalArrangement = Arrangement.Center,
itemCount = itemList.count(),
overflow = ContextualFlowRowOverflow.Clip
) { it ->

val item = itemList[it]
// itemList.forEach { item ->
SuggestionChip(
onClick = { /*TODO*/ },
label = { Text(text = item.text ?: "") },
modifier = Modifier
.width(item.width)
.height(70.dp)
.padding(10.dp)
)
// }
}

In this example, the items will wrap onto new rows within the FlowRow, and the entire layout is wrapped in a scrollable column, allowing the user to scroll vertically when there are more items than can fit on the screen.

When to Use Each Layout

  • Use Flow Row/Column when you need a simple, adaptive layout that responds well to dynamic content but doesn’t require intricate customization.
  • Use Contextual Flow Row/Column when you need more control over the layout behavior based on specific conditions, such as a fixed number of items per row or different behaviors for different screen sizes.

Conclusion

Both Flow Row/Column and Contextual Flow Row/Column provide powerful tools for managing dynamic layouts in Jetpack Compose. Flow Row/Column is ideal for general use cases where flexibility is key, while Contextual Flow Row/Column offers more control and customization for complex designs. Adding scrollable functionality to these layouts ensures that your UI remains responsive and accessible, even when handling large amounts of content.

By understanding the differences between these layout types, you can choose the right approach for your project, optimizing both the design and the user experience.

--

--

Charles Raj Iruthayaraj

Experienced software developer with hands-on experience in Android Application and iOS development.