Jetpack Compose Vertical Grid 单项跨度大小

Jetpack Compose Vertical Grid single item span size

在 xml 中,您可以在 GridLayoutManager 中使用 GridLayoutManager.SpanSizeLookup 来设置单个项目的跨度大小(项目将在行中使用多少列,例如,在 3 的网格中列我可以将第一个项目设置为跨度大小 3,这样它将使用网格的所有宽度),但是在 Compose 中我找不到方法,垂直网格只能设置全局跨度计数并添加项目,但不设置单个项目的跨度大小,有没有办法做到这一点?

目前不支持开箱即用。我现在解决这个问题的方法是使用 LazyColumn 然后项目是 Rows 并且在每个 Row 中你可以决定一个项目的宽度,使用 weight .

我已经实现了,在我的例子中,我有 headers(全宽)和等宽项目的单元格(根据屏幕的宽度,每个单元格可能有 1、2 或 3 个排)。这是一种解决方法,但在 VerticalGrid 提供本机支持之前,这是一个选项。

My solution is here - 查找 LazyListScope 扩展名。

根据答案改编代码,我创建了一个更“通用”的方法,它可以与 Adaptive 和 Fixed 一起使用,我对 Compose 很陌生,所以我接受建议

@Composable
fun HeaderGrid(cells: GridCells, content: HeaderGridScope.() -> Unit) {
    var columns = 1
    var minColumnWidth = 0.dp
    when (cells) {
        is GridCells.Fixed -> {
            columns = cells.count
            minColumnWidth = cells.minSize
        }
        is GridCells.Adaptive -> {
            val width = LocalContext.current.resources.displayMetrics.widthPixels
            val columnWidthPx = with(LocalDensity.current) { cells.minSize.toPx() }
            minColumnWidth = cells.minSize
            columns = ((width / columnWidthPx).toInt()).coerceAtLeast(1)
        }
    }
    LazyColumn(modifier = Modifier.fillMaxWidth()){
        content(HeaderGridScope(columns, minColumnWidth, this))
    }
}

fun <T>HeaderGridScope.gridItems(items: List<T>, content: @Composable (T) -> Unit) {
    items.chunked(numColumn).forEach {
        listScope.item {
            Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) {
                it.forEach { 
                    content(it)
                }
                if (it.size < numColumn) {
                    repeat(numColumn - it.size) {
                        Spacer(modifier = Modifier.width(columnWidth))
                    }
                }
            }
        }
    }
}

fun HeaderGridScope.header(content: @Composable BoxScope.() -> Unit) {
    listScope.item {
        Box(
            modifier = Modifier
                .fillMaxWidth(),
           content = content
        )
    }
}

data class HeaderGridScope(val numColumn: Int, val columnWidth: Dp, val listScope: LazyListScope)

sealed class GridCells {
    class Fixed(val count: Int, val minSize: Dp) : GridCells()
    class Adaptive(val minSize: Dp) : GridCells()
}

Jetpack Compose 版本 1.1.0-beta03LazyVerticalGrid 引入了水平跨度。

示例代码:

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)
    }
}