The Problem of Rows Breaking with Large Text

Reading time: about 3 minutes

Published

Originally published in Inclusive Android Apps-newsletter.

The Problem of Rows Breaking with Large Text
  1. The Problem of Rows Breaking with Large Text
  2. Read More
  3. Wrapping Up

This was originally sent as Issue #1 of my newsletter. Subscribe here to get future issues in your inbox first.

I was fixing an Android app and found buttons in a row getting cut off when I increased the font size. After diving into the code, the problem became clear: it was using Row when FlowRow was needed.

The Problem of Rows Breaking with Large Text

Let’s say we have this code:

Row(
  modifier = Modifier.fillMaxWidth(),
  verticalAlignment = Alignment.CenterVertically,
  horizontalArrangement = Arrangement.spacedBy(
    space = 16.dp,
    alignment = Alignment.CenterHorizontally
  )
) {
  Button(onClick = {}) {
    Icon(
      painter = painterResource(R.drawable.ic_arrow_back), 
      contentDescription = null
    )
    Text("Previous year")
  }
  Button(onClick = {}) {
    Text("Next year")
    Icon(
      painter = painterResource(R.drawable.ic_arrow), 
      contentDescription = null
    )
  }
}

Which, in turn, looks like this with the default font size:

Two buttons, Previous year and Next year, next to each other. They both have arrow icons, first pointing to the left, and latter to the right.

However, when we turn the font size up to 200%, things start breaking:

Now the Previous year button fits as before, but the Next year button, which is still next to the other button, has much less space, and the text goes on four lines. The arrow is not visible.

Who This Hurts

Why Developers Do This

Developers often test on their own devices with default settings, and everything looks fine. They don't realize that Row treats its children as a non-wrapping container, so if the content doesn't fit, it just overflows or gets cut off. There's no automatic wrapping behavior. It's not a bug in Row. It's just not designed to handle dynamic content that might change size.

The Solution

The most straightforward solution would be to use FlowRow:

FlowRow( // Changed from Row
  modifier = Modifier.fillMaxWidth(),
  itemVerticalAlignment = Alignment.CenterVertically, // Changed from verticalAlignment
  verticalArrangement = Arrangement.spacedBy(8.dp), // NEW: spacing between wrapped rows
  horizontalArrangement = Arrangement.spacedBy(
    space = 16.dp,
    alignment = Alignment.CenterHorizontally
  )
) {
  Button(onClick = {}) {
    Icon(
      painter = painterResource(R.drawable.ic_arrow_back), 
      contentDescription = null
    )
    Text("Previous year")
  }
  Button(onClick = {}) {
    Text("Next year")
    Icon(
      painter = painterResource(R.drawable.ic_arrow), 
      contentDescription = null
    )
  }
}

Which fixes the issues:

Buttons are now aligned on top of each other, arrows and texts are both visible.

FlowRow allows content to wrap on multiple rows if it doesn’t fit the horizontal space. Just remember not to set a fixed or maximum height for the FlowRow component!

When you use FlowRow, there are a couple of things to keep in mind:

FlowRow handles wrapping, but there’s one thing you’ll need to remember: each button still needs enough space to be readable. Test with large text and small screens to ensure everything works as expected for every user.

Note: FlowRow was added in Compose 1.4.0. If you're on an older version, consider updating or using a custom wrapping layout.

Read More

Flow layouts in Compose

Android Developers documentation has a whole page dedicated to flow layouts and how to use them. The page explains the features of flow layouts (FlowRow and FlowColumn), as well as how items can be arranged on the main and cross axes, aligned, and more. I recommend checking it out to learn more about flow layouts and how to use them.

Accessibility Scanner

Accessibility Scanner is a great tool for testing the accessibility of your app. It tests for four categories: content labeling, implementation, touch target size, and low contrast. While it does not reveal all possible accessibility problems, it can help with catching many low-hanging fruit.

Google has also provided a video about using the Accessibility scanner: Accessibility scanner - Accessibility on Android by Android Developers.

Wrapping Up

This was the first issue of the Inclusive Android Apps newsletter. What topics should I cover in the next issues?

Want to get future issues of Inclusive Android Apps delivered to your inbox? Subscribe here. Next issue covers building inclusive gender forms.