Grid

Functions summary

inline Unit
@Composable
@ExperimentalGridApi
Grid(
    noinline config: GridConfigurationScope.() -> Unit,
    modifier: Modifier,
    content: @Composable GridScope.() -> Unit
)

A 2D layout composable that arranges children into a grid of rows and columns.

Cmn

Functions

@Composable
@ExperimentalGridApi
inline fun Grid(
    noinline config: GridConfigurationScope.() -> Unit,
    modifier: Modifier = Modifier,
    content: @Composable GridScope.() -> Unit
): Unit

A 2D layout composable that arranges children into a grid of rows and columns.

The Grid allows defining explicit tracks (columns and rows) with various sizing capabilities, including fixed sizes (dp), flexible fractions (fr), percentages, and content-based sizing (Auto).

Key Features:

  • Explicit vs. Implicit: You define the main structure via config (explicit tracks). If items are placed outside these defined bounds, or if auto-placement creates new rows/columns, the grid automatically extends using implicit sizing (defaults to Auto).

  • Flexible Sizing: Use Fr units (e.g., 1.fr, 2.fr) to distribute available space proportionally among tracks.

  • Auto-placement: Items without a specific GridScope.gridItem modifier flow automatically into the next available cell based on the configured GridFlow. .

Example usage:

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Grid
import androidx.compose.foundation.layout.GridTrackSize
import androidx.compose.foundation.layout.GridTrackSize.Companion.Fixed
import androidx.compose.foundation.layout.columns
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Text
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

Grid(
    modifier = Modifier.fillMaxSize().padding(16.dp),
    config = {
        // Define 2 Columns:
        // Col 1: Fixed navigation sidebar width
        column(100.dp)
        // Col 2: Takes remaining space
        column(1.fr)

        // Define 3 Rows:
        // Row 1: Header (sized to content)
        row(GridTrackSize.Auto)
        // Row 2: Main Content (takes remaining height)
        row(1.fr)
        // Row 3: Footer (fixed height)
        row(60.dp)

        // Add 8dp space between all cells
        gap(8.dp)
    },
) {
    // 1. Header: Spans across both columns at the top
    Box(
        modifier =
            Modifier.gridItem(row = 1, column = 1, columnSpan = 2)
                .background(Color.Blue)
                .fillMaxSize(),
        contentAlignment = Alignment.Center,
    ) {
        Text("Header", color = Color.White)
    }

    // 2. Sidebar: Left column, middle row
    Box(
        modifier = Modifier.gridItem(row = 2, column = 1).background(Color.Green).fillMaxSize(),
        contentAlignment = Alignment.Center,
    ) {
        Text("Nav", color = Color.Black)
    }

    // 3. Main Content: Right column, middle row
    Box(
        modifier =
            Modifier.gridItem(row = 2, column = 2).background(Color.LightGray).fillMaxSize(),
        contentAlignment = Alignment.Center,
    ) {
        Text("Main Content Area")
    }

    // 4. Footer: Spans both columns at the bottom
    Box(
        modifier =
            Modifier.gridItem(row = 3, columnSpan = 2) // Column defaults to 1 if unspecified
                .background(Color.Magenta)
                .fillMaxSize(),
        contentAlignment = Alignment.Center,
    ) {
        Text("Footer", color = Color.White)
    }
}
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Grid
import androidx.compose.foundation.layout.GridTrackSize.Companion.Fixed
import androidx.compose.foundation.layout.columns
import androidx.compose.foundation.layout.rows
import androidx.compose.material.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

Grid(
    config = {
        columns(Fixed(60.dp), Fixed(60.dp), Fixed(60.dp))
        rows(Fixed(40.dp), Fixed(40.dp))
        gap(4.dp)
    },
    modifier = Modifier.background(Color.LightGray),
) {
    Text("1x1", Modifier.gridItem(row = 1, column = 1).background(Color.White))
    Text(
        "1x2 span col",
        Modifier.gridItem(row = 1, column = 2, columnSpan = 2).background(Color.Cyan),
    )
    Text(
        "2x1 span row",
        Modifier.gridItem(row = 1, column = 1, rowSpan = 2).background(Color.Yellow),
    )
    Text("2x2 span all", Modifier.gridItem(rows = 1..2, columns = 2..3).background(Color.Green))
}
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Grid
import androidx.compose.foundation.layout.GridFlow
import androidx.compose.foundation.layout.GridTrackSize.Companion.Fixed
import androidx.compose.foundation.layout.columns
import androidx.compose.material.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

Grid(
    config = {
        columns(Fixed(80.dp), Fixed(80.dp)) // Explicitly 2 columns
        // Rows are implicit
        flow = GridFlow.Row // Default
        gap(4.dp)
    }
) {
    // These items will fill row by row
    repeat(6) { index ->
        Text("Item $index", Modifier.background(Color(index * 40, 255 - index * 40, 128)))
    }
}
Parameters
noinline config: GridConfigurationScope.() -> Unit

A block that defines the columns, rows, and gaps of the grid. This block runs during the measure pass, enabling efficient updates based on state.

modifier: Modifier = Modifier

The modifier to be applied to the layout.

content: @Composable GridScope.() -> Unit

The content of the grid. Direct children can use GridScope.gridItem to configure their position and span.