LazyVerticalStaggeredGrid

Functions summary

Unit
@Composable
LazyVerticalStaggeredGrid(
    columns: StaggeredGridCells,
    modifier: Modifier,
    state: LazyStaggeredGridState,
    contentPadding: PaddingValues,
    reverseLayout: Boolean,
    verticalItemSpacing: Dp,
    horizontalArrangement: Arrangement.Horizontal,
    flingBehavior: FlingBehavior,
    userScrollEnabled: Boolean,
    overscrollEffect: OverscrollEffect?,
    content: LazyStaggeredGridScope.() -> Unit
)

Vertical staggered grid layout that composes and lays out only items currently visible on screen.

Cmn
Unit
@Composable
LazyVerticalStaggeredGrid(
    columns: StaggeredGridCells,
    modifier: Modifier,
    state: LazyStaggeredGridState,
    contentPadding: PaddingValues,
    reverseLayout: Boolean,
    verticalItemSpacing: Dp,
    horizontalArrangement: Arrangement.Horizontal,
    flingBehavior: FlingBehavior,
    userScrollEnabled: Boolean,
    overscrollEffect: OverscrollEffect?,
    cacheWindow: LazyLayoutCacheWindow,
    content: LazyStaggeredGridScope.() -> Unit
)

Vertical staggered grid layout that composes and lays out only items currently visible on screen.

Cmn

Functions

LazyVerticalStaggeredGrid

@Composable
fun LazyVerticalStaggeredGrid(
    columns: StaggeredGridCells,
    modifier: Modifier = Modifier,
    state: LazyStaggeredGridState = rememberLazyStaggeredGridState(),
    contentPadding: PaddingValues = PaddingValues(0.dp),
    reverseLayout: Boolean = false,
    verticalItemSpacing: Dp = 0.dp,
    horizontalArrangement: Arrangement.Horizontal = Arrangement.spacedBy(0.dp),
    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
    userScrollEnabled: Boolean = true,
    overscrollEffect: OverscrollEffect? = rememberOverscrollEffect(),
    content: LazyStaggeredGridScope.() -> Unit
): Unit

Vertical staggered grid layout that composes and lays out only items currently visible on screen.

Sample:

import androidx.compose.foundation.border
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
import androidx.compose.foundation.lazy.staggeredgrid.items
import androidx.compose.foundation.lazy.staggeredgrid.itemsIndexed
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

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

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

LazyVerticalStaggeredGrid(columns = StaggeredGridCells.Fixed(3)) {
    items(itemsList) { Text("Item is $it", itemModifier.height(80.dp)) }
    item { Text("Single item", itemModifier.height(100.dp)) }
    itemsIndexed(itemsIndexedList) { index, item ->
        Text("Item at index $index is $item", itemModifier.height(60.dp))
    }
}

Sample with custom item spans:

import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan
import androidx.compose.foundation.lazy.staggeredgrid.items
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

val sections = (0 until 25).toList().chunked(5)
LazyVerticalStaggeredGrid(
    columns = StaggeredGridCells.Fixed(3),
    horizontalArrangement = Arrangement.spacedBy(16.dp),
    verticalItemSpacing = 16.dp,
) {
    sections.forEachIndexed { index, items ->
        item(span = StaggeredGridItemSpan.FullLine) {
            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 = { StaggeredGridItemSpan.SingleLane },
        ) {
            Text("Item $it", Modifier.border(1.dp, Color.Blue).height(80.dp).wrapContentSize())
        }
    }
}
Parameters
columns: StaggeredGridCells

description of the size and number of staggered grid columns.

modifier: Modifier = Modifier

modifier to apply to the layout.

state: LazyStaggeredGridState = rememberLazyStaggeredGridState()

state object that can be used to control and observe staggered grid state.

contentPadding: PaddingValues = PaddingValues(0.dp)

padding around the content.

reverseLayout: Boolean = false

reverse the direction of scrolling and layout. When true, items are laid out in the reverse order and LazyStaggeredGridState.firstVisibleItemIndex == 0 means that grid is scrolled to the bottom.

verticalItemSpacing: Dp = 0.dp

vertical spacing between items.

horizontalArrangement: Arrangement.Horizontal = Arrangement.spacedBy(0.dp)

arrangement specifying horizontal spacing between items. The item arrangement specifics are ignored for now.

flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior()

logic responsible for handling fling.

userScrollEnabled: Boolean = true

whether scroll with gestures or accessibility actions are allowed. It is still possible to scroll programmatically through state when userScrollEnabled is set to false

overscrollEffect: OverscrollEffect? = rememberOverscrollEffect()

the OverscrollEffect that will be used to render overscroll for this layout. Note that the OverscrollEffect.node will be applied internally as well - you do not need to use Modifier.overscroll separately.

content: LazyStaggeredGridScope.() -> Unit

a lambda describing the staggered grid content. Inside this block you can use LazyStaggeredGridScope.items to present list of items or LazyStaggeredGridScope.item for a single one.

LazyVerticalStaggeredGrid

@Composable
fun LazyVerticalStaggeredGrid(
    columns: StaggeredGridCells,
    modifier: Modifier = Modifier,
    state: LazyStaggeredGridState = rememberLazyStaggeredGridState(),
    contentPadding: PaddingValues = PaddingValues(0.dp),
    reverseLayout: Boolean = false,
    verticalItemSpacing: Dp = 0.dp,
    horizontalArrangement: Arrangement.Horizontal = Arrangement.spacedBy(0.dp),
    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
    userScrollEnabled: Boolean = true,
    overscrollEffect: OverscrollEffect? = rememberOverscrollEffect(),
    cacheWindow: LazyLayoutCacheWindow = LazyStaggeredGridDefaults.cacheWindow(state),
    content: LazyStaggeredGridScope.() -> Unit
): Unit

Vertical staggered grid layout that composes and lays out only items currently visible on screen.

Sample:

import androidx.compose.foundation.border
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
import androidx.compose.foundation.lazy.staggeredgrid.items
import androidx.compose.foundation.lazy.staggeredgrid.itemsIndexed
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

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

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

LazyVerticalStaggeredGrid(columns = StaggeredGridCells.Fixed(3)) {
    items(itemsList) { Text("Item is $it", itemModifier.height(80.dp)) }
    item { Text("Single item", itemModifier.height(100.dp)) }
    itemsIndexed(itemsIndexedList) { index, item ->
        Text("Item at index $index is $item", itemModifier.height(60.dp))
    }
}

Sample with custom item spans:

import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan
import androidx.compose.foundation.lazy.staggeredgrid.items
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

val sections = (0 until 25).toList().chunked(5)
LazyVerticalStaggeredGrid(
    columns = StaggeredGridCells.Fixed(3),
    horizontalArrangement = Arrangement.spacedBy(16.dp),
    verticalItemSpacing = 16.dp,
) {
    sections.forEachIndexed { index, items ->
        item(span = StaggeredGridItemSpan.FullLine) {
            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 = { StaggeredGridItemSpan.SingleLane },
        ) {
            Text("Item $it", Modifier.border(1.dp, Color.Blue).height(80.dp).wrapContentSize())
        }
    }
}

Sample with custom cache window:

import androidx.compose.foundation.lazy.layout.LazyLayoutCacheWindow
import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
import androidx.compose.foundation.lazy.staggeredgrid.items
import androidx.compose.material3.Text

val itemsList = (0..100).toList()

LazyVerticalStaggeredGrid(
    columns = StaggeredGridCells.Fixed(3),
    cacheWindow = LazyLayoutCacheWindow(aheadFraction = 0.5f, behindFraction = 0.2f),
) {
    items(itemsList) { item -> Text("Item $item") }
}
Parameters
columns: StaggeredGridCells

description of the size and number of staggered grid columns.

modifier: Modifier = Modifier

modifier to apply to the layout.

state: LazyStaggeredGridState = rememberLazyStaggeredGridState()

state object that can be used to control and observe staggered grid state.

contentPadding: PaddingValues = PaddingValues(0.dp)

padding around the content.

reverseLayout: Boolean = false

reverse the direction of scrolling and layout. When true, items are laid out in the reverse order and LazyStaggeredGridState.firstVisibleItemIndex == 0 means that grid is scrolled to the bottom.

verticalItemSpacing: Dp = 0.dp

vertical spacing between items.

horizontalArrangement: Arrangement.Horizontal = Arrangement.spacedBy(0.dp)

arrangement specifying horizontal spacing between items. The item arrangement specifics are ignored for now.

flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior()

logic responsible for handling fling.

userScrollEnabled: Boolean = true

whether scroll with gestures or accessibility actions are allowed. It is still possible to scroll programmatically through state when userScrollEnabled is set to false

overscrollEffect: OverscrollEffect? = rememberOverscrollEffect()

the OverscrollEffect that will be used to render overscroll for this layout. Note that the OverscrollEffect.node will be applied internally as well - you do not need to use Modifier.overscroll separately.

cacheWindow: LazyLayoutCacheWindow = LazyStaggeredGridDefaults.cacheWindow(state)

LazyLayoutCacheWindow configuring the area ahead and behind the viewport to prefetch and retain items. The default cache window does not cache items while the user is not scrolling. Override this to tune scrolling performance, such as increasing the ahead window to reduce frame drops during scrolling or adding a behind window to retain recently visible items when scrolling back and forth.

content: LazyStaggeredGridScope.() -> Unit

a lambda describing the staggered grid content. Inside this block you can use LazyStaggeredGridScope.items to present list of items or LazyStaggeredGridScope.item for a single one.