LazyHorizontalStaggeredGrid

Composable Function
Common
@Composable
fun LazyHorizontalStaggeredGrid(
    rows: StaggeredGridCells,
    modifier: Modifier = Modifier,
    state: LazyStaggeredGridState = rememberLazyStaggeredGridState(),
    contentPadding: PaddingValues = PaddingValues(0.dp),
    reverseLayout: Boolean = false,
    verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(0.dp),
    horizontalItemSpacing: Dp = 0.dp,
    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
    userScrollEnabled: Boolean = true,
    overscrollEffect: OverscrollEffect? = rememberOverscrollEffect(),
    content: LazyStaggeredGridScope.() -> Unit,
)

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

Sample:

Sample with custom item spans:

Parameters

rows description of the size and number of staggered grid columns.
modifier modifier to apply to the layout.
state state object that can be used to control and observe staggered grid state.
contentPadding padding around the content.
reverseLayout 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 end.
verticalArrangement arrangement specifying vertical spacing between items. The item arrangement specifics are ignored for now.
horizontalItemSpacing horizontal spacing between items.
flingBehavior logic responsible for handling fling.
userScrollEnabled 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 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 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.
Common
Deprecated Use the non deprecated overload
@Composable
fun LazyHorizontalStaggeredGrid(
    rows: StaggeredGridCells,
    modifier: Modifier = Modifier,
    state: LazyStaggeredGridState = rememberLazyStaggeredGridState(),
    contentPadding: PaddingValues = PaddingValues(0.dp),
    reverseLayout: Boolean = false,
    verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(0.dp),
    horizontalItemSpacing: Dp = 0.dp,
    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
    userScrollEnabled: Boolean = true,
    content: LazyStaggeredGridScope.() -> Unit,
)

Code Examples

LazyHorizontalStaggeredGridSample

@Preview
@Composable
fun LazyHorizontalStaggeredGridSample() {
    val itemsList = (0..5).toList()
    val itemsIndexedList = listOf("A", "B", "C")
    val itemModifier = Modifier.border(1.dp, Color.Blue).padding(16.dp).wrapContentSize()
    LazyHorizontalStaggeredGrid(rows = StaggeredGridCells.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)
        }
    }
}

LazyHorizontalStaggeredGridSpanSample

@Preview
@Composable
fun LazyHorizontalStaggeredGridSpanSample() {
    val sections = (0 until 25).toList().chunked(5)
    LazyHorizontalStaggeredGrid(
        rows = StaggeredGridCells.Fixed(3),
        verticalArrangement = Arrangement.spacedBy(16.dp),
        horizontalItemSpacing = 16.dp,
    ) {
        sections.forEachIndexed { index, items ->
            item(span = StaggeredGridItemSpan.FullLine) {
                Text(
                    "This is section $index",
                    Modifier.border(1.dp, Color.Gray).padding(16.dp).wrapContentSize(),
                )
            }
            items(
                items,
                // not required as it is the default
                span = { StaggeredGridItemSpan.SingleLane },
            ) {
                Text("Item $it", Modifier.border(1.dp, Color.Blue).width(80.dp).wrapContentSize())
            }
        }
    }
}