Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jetpack Compose Vertical Grid single item span size

In xml you can use GridLayoutManager.SpanSizeLookup in GridLayoutManager to set the span size on single items (How many columns the item will use in the row, like for example, in a grid of 3 columns I can set the first item to be span size 3 so it will use all the width of the grid), but in Compose I can't find a way to do it, the vertical grid only have a way set the global span count and add items, but not set the span size of an individual item, is there a way to do it?

like image 390
Jordy Mendoza Avatar asked Nov 15 '25 03:11

Jordy Mendoza


2 Answers

Jetpack Compose version 1.1.0-beta03 introduced horizontal spans to LazyVerticalGrid.

Example code:

val list by remember { mutableStateOf(listOf("A", "E", "I", "O", "U")) }

LazyVerticalGrid(
    cells = GridCells.Fixed(2)
) {
    // Spanned Item:
    item(
        span = {
            // Replace "maxCurrentLineSpan" with the number of spans this item should take.
            // Use "maxCurrentLineSpan" if you want to take full width.
            GridItemSpan(maxCurrentLineSpan)
        }
    ) {
        Text("Vowels")
    }

    // Other items:
    items(list) { item ->
        Text(item)
    }
}

like image 76
Mahmudul Hasan Shohag Avatar answered Nov 17 '25 16:11

Mahmudul Hasan Shohag


There is no support for this out of the box at present. The way I have solved this for now is to use a LazyColumn then the items are Rows and in each Row you can decide how wide an item is, using weight.

I have implemented and in my case I have headers (full width), and cells of items of equal width (based on how wide the screen is, there could be 1, 2 or 3 cells per row). It's a workaround, but until there is native support from VerticalGrid this is an option.

My solution is here - look for the LazyListScope extensions.

Edit: this is no longer necessary as LazyVerticalGrid supports spans now, here's an example

LazyVerticalGrid(
    columns = GridCells.Adaptive(
        minSize = WeatherCardWidth,
    ),
    modifier = modifier,
    contentPadding = PaddingValues(all = MarginDouble),
    horizontalArrangement = Arrangement.spacedBy(MarginDouble),
    verticalArrangement = Arrangement.spacedBy(MarginDouble),
) {
    state.forecastItems.forEach { dayForecast ->
        item(
            key = dayForecast.header.id,
            span = { GridItemSpan(maxLineSpan) }
        ) {
            ForecastHeader(
                state = dayForecast.header,
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(vertical = MarginDouble),
            )
        }
        items(
            items = dayForecast.forecast,
            key = { hourForecast -> hourForecast.id }
        ) { hourForecast ->
            ForecastWeatherCard(
                state = hourForecast,
                modifier = Modifier.fillMaxWidth(),
            )
        }
    }
}
like image 45
Francesc Avatar answered Nov 17 '25 17:11

Francesc



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!