If you don't mind using an unstable API, you can use LazyVerticalGrid and make item take the full width with the span parameter, as @Mustafa pointed out:
LazyVerticalGrid(
cells = GridCells.Fixed(spanCount),
) {
item(
span = { GridItemSpan(spanCount) }
) {
Text("Title")
}
items(10) {
Text(it.toString())
}
}
Until it's stable, it's recommended
using stable components like LazyColumn and Row to achieve the same result.
It can be done by implementing gridItems to be used with LazyColumn.
fun LazyListScope.gridItems(
count: Int,
nColumns: Int,
horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
itemContent: @Composable BoxScope.(Int) -> Unit,
) {
gridItems(
data = List(count) { it },
nColumns = nColumns,
horizontalArrangement = horizontalArrangement,
itemContent = itemContent,
)
}
fun <T> LazyListScope.gridItems(
data: List<T>,
nColumns: Int,
horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
key: ((item: T) -> Any)? = null,
itemContent: @Composable BoxScope.(T) -> Unit,
) {
val rows = if (data.isEmpty()) 0 else 1 + (data.count() - 1) / nColumns
items(rows) { rowIndex ->
Row(horizontalArrangement = horizontalArrangement) {
for (columnIndex in 0 until nColumns) {
val itemIndex = rowIndex * nColumns + columnIndex
if (itemIndex < data.count()) {
val item = data[itemIndex]
androidx.compose.runtime.key(key?.invoke(item)) {
Box(
modifier = Modifier.weight(1f, fill = true),
propagateMinConstraints = true
) {
itemContent.invoke(this, item)
}
}
} else {
Spacer(Modifier.weight(1f, fill = true))
}
}
}
}
}
Usage:
LazyColumn {
item {
Text(text = "My LazyColumn Title")
}
// with count
gridItems(10, nColumns = 4) { index ->
Box(
modifier = Modifier
.size(50.dp)
.padding(5.dp)
.background(Color.Gray)
)
}
// or with list of items
gridItems(listOf(1,2,3), nColumns = 4) { item ->
Box(
modifier = Modifier
.size(50.dp)
.padding(5.dp)
.background(Color.Gray)
)
}
}