androidx.compose.foundation.lazy.grid

Interfaces

GridCells

This class describes the count and the sizes of columns in vertical grids, or rows in horizontal grids.

Cmn
LazyGridItemInfo

Contains useful information about an individual item in lazy grids like LazyVerticalGrid.

Cmn
LazyGridItemScope

Receiver scope being used by the item content parameter of LazyVerticalGrid.

Cmn
LazyGridItemSpanScope

Scope of lambdas used to calculate the spans of items in lazy grids.

Cmn
LazyGridLayoutInfo

Contains useful information about the currently displayed layout state of lazy grids like LazyVerticalGrid.

Cmn
LazyGridScope

Receiver scope which is used by LazyVerticalGrid.

Cmn

Classes

GridCells.Adaptive

Defines a grid with as many rows or columns as possible on the condition that every cell has at least minSize space and all extra space distributed evenly.

Cmn
GridCells.Fixed

Defines a grid with fixed number of rows or columns.

Cmn
GridCells.FixedSize

Defines a grid with as many rows or columns as possible on the condition that every cell takes exactly size space.

Cmn
GridItemSpan

Represents the span of an item in a LazyVerticalGrid.

Cmn
LazyGridState

A state object that can be hoisted to control and observe scrolling.

Cmn

Annotations

LazyGridScopeMarker

DSL marker used to distinguish between lazy grid dsl scope and the item content scope.

Cmn

Top-level functions summary

GridItemSpan
GridItemSpan(currentLineSpan: @IntRange(from = 1) Int)

Creates a GridItemSpan with a specified currentLineSpan.

Cmn
Unit
@Composable
LazyHorizontalGrid(
    rows: GridCells,
    modifier: Modifier,
    state: LazyGridState,
    contentPadding: PaddingValues,
    reverseLayout: Boolean,
    horizontalArrangement: Arrangement.Horizontal,
    verticalArrangement: Arrangement.Vertical,
    flingBehavior: FlingBehavior,
    userScrollEnabled: Boolean,
    content: LazyGridScope.() -> Unit
)

A lazy horizontal grid layout.

Cmn
Unit
@Composable
LazyVerticalGrid(
    columns: GridCells,
    modifier: Modifier,
    state: LazyGridState,
    contentPadding: PaddingValues,
    reverseLayout: Boolean,
    verticalArrangement: Arrangement.Vertical,
    horizontalArrangement: Arrangement.Horizontal,
    flingBehavior: FlingBehavior,
    userScrollEnabled: Boolean,
    content: LazyGridScope.() -> Unit
)

A lazy vertical grid layout.

Cmn
LazyGridState
@Composable
rememberLazyGridState(
    initialFirstVisibleItemIndex: Int,
    initialFirstVisibleItemScrollOffset: Int
)

Creates a LazyGridState that is remembered across compositions.

Cmn

Extension functions summary

inline Unit
<T : Any?> LazyGridScope.items(
    items: Array<T>,
    noinline key: ((item) -> Any)?,
    noinline span: (LazyGridItemSpanScope.(item) -> GridItemSpan)?,
    noinline contentType: (item) -> Any,
    crossinline itemContent: @Composable LazyGridItemScope.(item) -> Unit
)

Adds an array of items.

Cmn
inline Unit
<T : Any?> LazyGridScope.items(
    items: List<T>,
    noinline key: ((item) -> Any)?,
    noinline span: (LazyGridItemSpanScope.(item) -> GridItemSpan)?,
    noinline contentType: (item) -> Any,
    crossinline itemContent: @Composable LazyGridItemScope.(item) -> Unit
)

Adds a list of items.

Cmn
inline Unit
<T : Any?> LazyGridScope.itemsIndexed(
    items: Array<T>,
    noinline key: ((index: Int, item) -> Any)?,
    noinline span: (LazyGridItemSpanScope.(index: Int, item) -> GridItemSpan)?,
    crossinline contentType: (index: Int, item) -> Any,
    crossinline itemContent: @Composable LazyGridItemScope.(index: Int, item) -> Unit
)

Adds an array of items where the content of an item is aware of its index.

Cmn
inline Unit
<T : Any?> LazyGridScope.itemsIndexed(
    items: List<T>,
    noinline key: ((index: Int, item) -> Any)?,
    noinline span: (LazyGridItemSpanScope.(index: Int, item) -> GridItemSpan)?,
    crossinline contentType: (index: Int, item) -> Any,
    crossinline itemContent: @Composable LazyGridItemScope.(index: Int, item) -> Unit
)

Adds a list of items where the content of an item is aware of its index.

Cmn

Top-level functions

GridItemSpan

fun GridItemSpan(currentLineSpan: @IntRange(from = 1) Int): GridItemSpan

Creates a GridItemSpan with a specified currentLineSpan. This will be the horizontal span for an item of a LazyVerticalGrid.

LazyHorizontalGrid

@Composable
fun LazyHorizontalGrid(
    rows: GridCells,
    modifier: Modifier = Modifier,
    state: LazyGridState = rememberLazyGridState(),
    contentPadding: PaddingValues = PaddingValues(0.dp),
    reverseLayout: Boolean = false,
    horizontalArrangement: Arrangement.Horizontal = if (!reverseLayout) Arrangement.Start else Arrangement.End,
    verticalArrangement: Arrangement.Vertical = Arrangement.Top,
    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
    userScrollEnabled: Boolean = true,
    content: LazyGridScope.() -> Unit
): Unit

A lazy horizontal grid layout. It composes only visible columns of the grid.

Sample:

import androidx.compose.foundation.border
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.lazy.grid.itemsIndexed
import androidx.compose.material.Text

val itemsList = (0..5).toList()
val itemsIndexedList = listOf("A", "B", "C")

val itemModifier = Modifier.border(1.dp, Color.Blue).width(80.dp).wrapContentSize()

LazyHorizontalGrid(
    rows = GridCells.Fixed(3),
    horizontalArrangement = Arrangement.spacedBy(16.dp),
    verticalArrangement = Arrangement.spacedBy(16.dp)
) {
    items(itemsList) {
        Text("Item is $it", itemModifier)
    }

    item {
        Text("Single item", itemModifier)
    }

    itemsIndexed(itemsIndexedList) { index, item ->
        Text("Item at index $index is $item", itemModifier)
    }
}

Sample with custom item spans:

import androidx.compose.foundation.border
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.material.Text

val sections = (0 until 25).toList().chunked(5)
LazyHorizontalGrid(
    rows = GridCells.Fixed(3),
    horizontalArrangement = Arrangement.spacedBy(16.dp),
    verticalArrangement = Arrangement.spacedBy(16.dp)
) {
    sections.forEachIndexed { index, items ->
        item(span = { GridItemSpan(maxLineSpan) }) {
            Text(
                "This is section $index",
                Modifier.border(1.dp, Color.Gray).width(80.dp).wrapContentSize()
            )
        }
        items(
            items,
            // not required as it is the default
            span = { GridItemSpan(1) }
        ) {
            Text(
                "Item $it",
                Modifier.border(1.dp, Color.Blue).width(80.dp).wrapContentSize()
            )
        }
    }
}
Parameters
rows: GridCells

a class describing how cells form rows, see GridCells doc for more information

modifier: Modifier = Modifier

the modifier to apply to this layout

state: LazyGridState = rememberLazyGridState()

the state object to be used to control or observe the list's state

contentPadding: PaddingValues = PaddingValues(0.dp)

specify a padding around the whole content

reverseLayout: Boolean = false

reverse the direction of scrolling and layout. When true, items are laid out in the reverse order and LazyGridState.firstVisibleItemIndex == 0 means that grid is scrolled to the end. Note that reverseLayout does not change the behavior of horizontalArrangement, e.g. with 123### becomes 321###.

horizontalArrangement: Arrangement.Horizontal = if (!reverseLayout) Arrangement.Start else Arrangement.End

The horizontal arrangement of the layout's children

verticalArrangement: Arrangement.Vertical = Arrangement.Top

The vertical arrangement of the layout's children

flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior()

logic describing fling behavior

userScrollEnabled: Boolean = true

whether the scrolling via the user gestures or accessibility actions is allowed. You can still scroll programmatically using the state even when it is disabled.

content: LazyGridScope.() -> Unit

the LazyGridScope which describes the content

LazyVerticalGrid

@Composable
fun LazyVerticalGrid(
    columns: GridCells,
    modifier: Modifier = Modifier,
    state: LazyGridState = rememberLazyGridState(),
    contentPadding: PaddingValues = PaddingValues(0.dp),
    reverseLayout: Boolean = false,
    verticalArrangement: Arrangement.Vertical = if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,
    horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
    userScrollEnabled: Boolean = true,
    content: LazyGridScope.() -> Unit
): Unit

A lazy vertical grid layout. It composes only visible rows of the grid.

Sample:

import androidx.compose.foundation.border
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.lazy.grid.itemsIndexed
import androidx.compose.material.Text

val itemsList = (0..5).toList()
val itemsIndexedList = listOf("A", "B", "C")

val itemModifier = Modifier.border(1.dp, Color.Blue).height(80.dp).wrapContentSize()

LazyVerticalGrid(
    columns = GridCells.Fixed(3)
) {
    items(itemsList) {
        Text("Item is $it", itemModifier)
    }
    item {
        Text("Single item", itemModifier)
    }
    itemsIndexed(itemsIndexedList) { index, item ->
        Text("Item at index $index is $item", itemModifier)
    }
}

Sample with custom item spans:

import androidx.compose.foundation.border
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.material.Text

val sections = (0 until 25).toList().chunked(5)
LazyVerticalGrid(
    columns = GridCells.Fixed(3),
    horizontalArrangement = Arrangement.spacedBy(16.dp),
    verticalArrangement = Arrangement.spacedBy(16.dp)
) {
    sections.forEachIndexed { index, items ->
        item(span = { GridItemSpan(maxLineSpan) }) {
            Text(
                "This is section $index",
                Modifier.border(1.dp, Color.Gray).height(80.dp).wrapContentSize()
            )
        }
        items(
            items,
            // not required as it is the default
            span = { GridItemSpan(1) }
        ) {
            Text(
                "Item $it",
                Modifier.border(1.dp, Color.Blue).height(80.dp).wrapContentSize()
            )
        }
    }
}
Parameters
columns: GridCells

describes the count and the size of the grid's columns, see GridCells doc for more information

modifier: Modifier = Modifier

the modifier to apply to this layout

state: LazyGridState = rememberLazyGridState()

the state object to be used to control or observe the list's state

contentPadding: PaddingValues = PaddingValues(0.dp)

specify a padding around the whole content

reverseLayout: Boolean = false

reverse the direction of scrolling and layout. When true, items will be laid out in the reverse order and LazyGridState.firstVisibleItemIndex == 0 means that grid is scrolled to the bottom. Note that reverseLayout does not change the behavior of verticalArrangement, e.g. with Arrangement.Top (top) 123### (bottom) becomes (top) 321### (bottom).

verticalArrangement: Arrangement.Vertical = if (!reverseLayout) Arrangement.Top else Arrangement.Bottom

The vertical arrangement of the layout's children

horizontalArrangement: Arrangement.Horizontal = Arrangement.Start

The horizontal arrangement of the layout's children

flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior()

logic describing fling behavior

userScrollEnabled: Boolean = true

whether the scrolling via the user gestures or accessibility actions is allowed. You can still scroll programmatically using the state even when it is disabled.

content: LazyGridScope.() -> Unit

the LazyGridScope which describes the content

rememberLazyGridState

@Composable
fun rememberLazyGridState(
    initialFirstVisibleItemIndex: Int = 0,
    initialFirstVisibleItemScrollOffset: Int = 0
): LazyGridState

Creates a LazyGridState that is remembered across compositions.

Changes to the provided initial values will not result in the state being recreated or changed in any way if it has already been created.

Parameters
initialFirstVisibleItemIndex: Int = 0

the initial value for LazyGridState.firstVisibleItemIndex

initialFirstVisibleItemScrollOffset: Int = 0

the initial value for LazyGridState.firstVisibleItemScrollOffset

Extension functions

inline fun <T : Any?> LazyGridScope.items(
    items: Array<T>,
    noinline key: ((item) -> Any)? = null,
    noinline span: (LazyGridItemSpanScope.(item) -> GridItemSpan)? = null,
    noinline contentType: (item) -> Any = { null },
    crossinline itemContent: @Composable LazyGridItemScope.(item) -> Unit
): Unit

Adds an array of items.

Parameters
items: Array<T>

the data array

noinline key: ((item) -> Any)? = null

a factory of stable and unique keys representing the item. Using the same key for multiple items in the grid is not allowed. Type of the key should be saveable via Bundle on Android. If null is passed the position in the grid will represent the key. When you specify the key the scroll position will be maintained based on the key, which means if you add/remove items before the current visible item the item with the given key will be kept as the first visible one.

noinline span: (LazyGridItemSpanScope.(item) -> GridItemSpan)? = null

define custom spans for the items. Default is 1x1. It is good practice to leave it null when this matches the intended behavior, as providing a custom implementation impacts performance

noinline contentType: (item) -> Any = { null }

a factory of the content types for the item. The item compositions of the same type could be reused more efficiently. Note that null is a valid type and items of such type will be considered compatible.

crossinline itemContent: @Composable LazyGridItemScope.(item) -> Unit

the content displayed by a single item

inline fun <T : Any?> LazyGridScope.items(
    items: List<T>,
    noinline key: ((item) -> Any)? = null,
    noinline span: (LazyGridItemSpanScope.(item) -> GridItemSpan)? = null,
    noinline contentType: (item) -> Any = { null },
    crossinline itemContent: @Composable LazyGridItemScope.(item) -> Unit
): Unit

Adds a list of items.

Parameters
items: List<T>

the data list

noinline key: ((item) -> Any)? = null

a factory of stable and unique keys representing the item. Using the same key for multiple items in the grid is not allowed. Type of the key should be saveable via Bundle on Android. If null is passed the position in the grid will represent the key. When you specify the key the scroll position will be maintained based on the key, which means if you add/remove items before the current visible item the item with the given key will be kept as the first visible one.

noinline span: (LazyGridItemSpanScope.(item) -> GridItemSpan)? = null

define custom spans for the items. Default is 1x1. It is good practice to leave it null when this matches the intended behavior, as providing a custom implementation impacts performance

noinline contentType: (item) -> Any = { null }

a factory of the content types for the item. The item compositions of the same type could be reused more efficiently. Note that null is a valid type and items of such type will be considered compatible.

crossinline itemContent: @Composable LazyGridItemScope.(item) -> Unit

the content displayed by a single item

itemsIndexed

inline fun <T : Any?> LazyGridScope.itemsIndexed(
    items: Array<T>,
    noinline key: ((index: Int, item) -> Any)? = null,
    noinline span: (LazyGridItemSpanScope.(index: Int, item) -> GridItemSpan)? = null,
    crossinline contentType: (index: Int, item) -> Any = { _, _ -> null },
    crossinline itemContent: @Composable LazyGridItemScope.(index: Int, item) -> Unit
): Unit

Adds an array of items where the content of an item is aware of its index.

Parameters
items: Array<T>

the data array

noinline key: ((index: Int, item) -> Any)? = null

a factory of stable and unique keys representing the item. Using the same key for multiple items in the grid is not allowed. Type of the key should be saveable via Bundle on Android. If null is passed the position in the grid will represent the key. When you specify the key the scroll position will be maintained based on the key, which means if you add/remove items before the current visible item the item with the given key will be kept as the first visible one.

noinline span: (LazyGridItemSpanScope.(index: Int, item) -> GridItemSpan)? = null

define custom spans for the items. Default is 1x1. It is good practice to leave it null when this matches the intended behavior, as providing a custom implementation impacts performance

crossinline contentType: (index: Int, item) -> Any = { _, _ -> null }

a factory of the content types for the item. The item compositions of the same type could be reused more efficiently. Note that null is a valid type and items of such type will be considered compatible.

crossinline itemContent: @Composable LazyGridItemScope.(index: Int, item) -> Unit

the content displayed by a single item

inline fun <T : Any?> LazyGridScope.itemsIndexed(
    items: List<T>,
    noinline key: ((index: Int, item) -> Any)? = null,
    noinline span: (LazyGridItemSpanScope.(index: Int, item) -> GridItemSpan)? = null,
    crossinline contentType: (index: Int, item) -> Any = { _, _ -> null },
    crossinline itemContent: @Composable LazyGridItemScope.(index: Int, item) -> Unit
): Unit

Adds a list of items where the content of an item is aware of its index.

Parameters
items: List<T>

the data list

noinline key: ((index: Int, item) -> Any)? = null

a factory of stable and unique keys representing the item. Using the same key for multiple items in the grid is not allowed. Type of the key should be saveable via Bundle on Android. If null is passed the position in the grid will represent the key. When you specify the key the scroll position will be maintained based on the key, which means if you add/remove items before the current visible item the item with the given key will be kept as the first visible one.

noinline span: (LazyGridItemSpanScope.(index: Int, item) -> GridItemSpan)? = null

define custom spans for the items. Default is 1x1. It is good practice to leave it null when this matches the intended behavior, as providing a custom implementation impacts performance

crossinline contentType: (index: Int, item) -> Any = { _, _ -> null }

a factory of the content types for the item. The item compositions of the same type could be reused more efficiently. Note that null is a valid type and items of such type will be considered compatible.

crossinline itemContent: @Composable LazyGridItemScope.(index: Int, item) -> Unit

the content displayed by a single item