Search code examples
androidandroid-jetpackandroid-jetpack-compose

How can I add a stickyHeader to LazyVerticalGrid like LazyColumn in jetpack compose?


I want to achieve a UI effect like this:

<GridView>
    <Title of Grid content in a single row />
    <Grid content arranged in the form of n * 3 />

    <Title of Grid content in a single row />
    <Grid content arranged in the form of n * 3 />

    <Title of Grid content in a single row />
    <Grid content arranged in the form of n * 3 />
</GridView>

But I am not able to add the row to the LazyColumnGrid.

I tried using the LazyColumnGrid around Column with vertical scroll, but it says it's wrong to nest two scrollable views in the same direction.

Also, I tried to use item{ } on <Title of Grid />, but that made item{ } an item in the gridview, not a single row.

So how can I achieve this in a simple way?


Solution

  • You can't really create a sticky header with Compose's LazyGrid apis, but you can create a header as follow:

    
    fun LazyGridScope.header(
        content: @Composable LazyGridItemScope.() -> Unit
    ) {
        item(span = { GridItemSpan(this.maxLineSpan) }, content = content)
    }
    

    The code uses the span block with this.maxLineSpan which becomes a full-width header.

    So, you can use it like this

    LazyVerticalGrid(
        ...
    ) {
        header {
            Text("Header Title") // or any composable for your single row
        }
        items(count = n * 3) {
            GridItem() 
        }
    
    
        header {
            Text("Header Title") // or any composable for your single row
        }
        items(count = n * 3) {
            GridItem() 
        }
        
    }
    

    BONUS You can also offset your cells this way

    fun LazyGridScope.offSetCells(count: Int) {
        item(span = { GridItemSpan(count) }) {}
    }
    
    ...
    
    LazyVerticalGrid(
       ...
    ) {
        offsetCells(count = 3)
    }