FlexBox

Composable Function

Common
@Composable
@ExperimentalFlexBoxApi
inline fun FlexBox(
    modifier: Modifier = Modifier,
    config: FlexBoxConfig = FlexBoxConfig,
    content: @Composable FlexBoxScope.() -> Unit,
)

A layout that aligns its children in a single direction (the main axis) and allows them to wrap onto multiple lines. FlexBox provides a highly configurable layout system, serving as a flexible superset of Row, Column, FlowRow, and FlowColumn.

The layout behavior of the container is controlled by the config parameter, which dictates the flex direction, wrapping behavior, alignment, and spacing. Individual children can further control their own flexibility (grow, shrink, and base size) and alignment using the FlexBoxScope.flex modifier.

Understanding FlexBox requires familiarity with its axes:

  • Main Axis: The primary direction along which items are laid out, determined by the FlexBoxConfigScope.direction. Items are placed starting from the main-start edge and flowing toward the main-end edge. Defaults to FlexDirection.Row. - For FlexDirection.Row: main-start is the layout's start edge (left in LTR, right in RTL) and main-end is the end edge (right in LTR, left in RTL). - For FlexDirection.RowReverse: main-start is the layout's end edge (right in LTR, left in * RTL) and main-end is the start edge (left in LTR, right in RTL). - For FlexDirection.Column: main-start is the top edge and main-end is the bottom edge. - For FlexDirection.ColumnReverse: main-start is the bottom edge and main-end is the top edge.
  • Cross Axis: The axis perpendicular to the main axis. Wrapped lines are added, and items are aligned within their lines, starting from the cross-start edge and flowing toward the cross-end edge. - For horizontal directions (FlexDirection.Row and FlexDirection.RowReverse): cross-start is the top edge and cross-end is the bottom edge. - For vertical directions (FlexDirection.Column and FlexDirection.ColumnReverse): cross-start is the layout's start edge and cross-end is the end edge.

Children can dictate how they share available space using the FlexBoxScope.flex modifier:

  • FlexConfigScope.grow: Defines how much of the remaining positive free space the item should consume relative to its siblings. Defaults to 0f (no growth).
  • FlexConfigScope.shrink: Defines how much the item should shrink when the combined sizes of the items exceed the container's main axis size. Defaults to 1f.
  • FlexConfigScope.basis: Sets the initial main axis size of the item before any free space distribution (grow or shrink) is calculated. Defaults to FlexBasis.Auto.

FlexBox provides granular control over the placement of items and lines:

  • FlexBoxConfigScope.wrap: Controls whether items are forced onto a single line or allowed to wrap onto multiple lines when they exceed the available space. Defaults to FlexWrap.NoWrap.
  • FlexBoxConfigScope.justifyContent: Distributes items along the main axis (for example, spacing them evenly). Defaults to FlexJustifyContent.Start.
  • FlexBoxConfigScope.alignItems: Aligns items within a specific line along the cross axis (for example, centering them vertically within a Row). Defaults to FlexAlignItems.Start.
  • FlexConfigScope.alignSelf: Allows an individual item to override the container's FlexBoxConfigScope.alignItems. Defaults to FlexAlignSelf.Auto.
  • FlexBoxConfigScope.alignContent:Distributes multiple wrapped lines along the cross axis. This only applies when wrapping is enabled. Defaults to FlexAlignContent.Start.

By default, children are placed in a horizontal row without wrapping. If wrapping is disabled (FlexWrap.NoWrap), children will shrink to fit the container if they have a shrink factor > 0. If children cannot shrink enough due to their minimum intrinsic sizes, they will visually overflow the container's bounds along the main axis. You can explicitly apply Modifier.clipToBounds on the FlexBox if you wish to hide overflowing content.

Parameters

modifierThe modifier to be applied to the FlexBox container.
configA FlexBoxConfig that configures the container's layout properties. Defaults to a horizontal row layout without wrapping, with items aligned to the start on both axes and no gaps between items.
contentThe content of the FlexBox, defined within a FlexBoxScope.

Code Examples

SimpleFlexBox

@Composable
@OptIn(ExperimentalFlexBoxApi::class)
fun SimpleFlexBox() {
    // FlexBox defaults to a Row-like layout (FlexDirection.Row).
    // The children will be laid out horizontally.
    FlexBox(
        modifier = Modifier.fillMaxWidth(),
        config = {
            direction(
                if (constraints.maxWidth < 400.dp.roundToPx()) FlexDirection.Column
                else FlexDirection.Row
            )
        },
    ) {
        // This child has a fixed size and will not flex.
        Box(
            modifier = Modifier.size(80.dp).background(Color.Magenta),
            contentAlignment = Alignment.Center,
        ) {
            Text("Fixed")
        }
        // This child has a grow factor of 1. It will take up 1/3 of the remaining space.
        Box(
            modifier = Modifier.height(80.dp).flex { grow(1f) }.background(Color.Yellow),
            contentAlignment = Alignment.Center,
        ) {
            Text("Grow = 1")
        }
        // This child has a growth factor of 2. It will take up 2/3 of the remaining space.
        Box(
            modifier = Modifier.height(80.dp).flex { grow(2f) }.background(Color.Green),
            contentAlignment = Alignment.Center,
        ) {
            Text("Grow = 2")
        }
    }
}