Grid
Composable Function
Common
@Composable
@ExperimentalGridApi
inline fun Grid(
noinline config: GridConfigurationScope.() -> Unit,
modifier: Modifier = Modifier,
content: @Composable GridScope.() -> 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 toAuto). - Flexible Sizing: Use
Frunits (e.g.,1.fr,2.fr) to distribute available space proportionally among tracks. - Auto-placement: Items without a specific
GridScope.gridItemmodifier flow automatically into the next available cell based on the configuredGridFlow. .
Parameters
| config | 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 | The modifier to be applied to the layout. |
| content | The content of the grid. Direct children can use GridScope.gridItem to configure their position and span. |
Code Examples
GridWithAutoPlacement
@Composable
@OptIn(ExperimentalGridApi::class)
fun GridWithAutoPlacement() {
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)))
}
}
}
GridWithSpanningItems
@Composable
@OptIn(ExperimentalGridApi::class)
fun GridWithSpanningItems() {
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))
}
}
SimpleGrid
@Composable
@OptIn(ExperimentalGridApi::class)
fun SimpleGrid() {
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)
}
}
}