Jetpack Compose自定义布局 --->交错网格布局(StaggeredVerticalGrid)

Jetpack Compose--->交错网格布局

  1. 源码链接:https://github.com/android/compose-samples/tree/main/Owl

  2. 这个是来自谷歌官方的一个Jetpack Compose开源案例中的自定义布局,记录以下Compose自定义布局的使用。

  3. StaggeredVerticalGrid

    @Composable
    fun StaggeredVerticalGrid(
        modifier: Modifier = Modifier,
        maxColumnWidth: Dp,
        content: @Composable () -> Unit
    ) {
        Layout(
            content = content,
            modifier = modifier
        ) { measurables, constraints ->
            check(constraints.hasBoundedWidth) {
                "Unbounded width not supported"
            }
            val columns = ceil(constraints.maxWidth / maxColumnWidth.toPx()).toInt()
            val columnWidth = constraints.maxWidth / columns
    
            val itemConstraints = constraints.copy(maxWidth = columnWidth)
            val colHeights = IntArray(columns) { 0 } // track each column's height
            val placeables = measurables.map { measurable ->
                val column = shortestColumn(colHeights)
                val placeable = measurable.measure(itemConstraints)
                colHeights[column] += placeable.height
                placeable
            }
    
            val height = colHeights.maxOrNull()?.coerceIn(constraints.minHeight, constraints.maxHeight)
                ?: constraints.minHeight
            layout(
                width = constraints.maxWidth,
                height = height
            ) {
                val colY = IntArray(columns) { 0 }
                placeables.forEach { placeable ->
                    val column = shortestColumn(colY)
                    placeable.place(
                        x = columnWidth * column,
                        y = colY[column]
                    )
                    colY[column] += placeable.height
                }
            }
        }
    }
    
    private fun shortestColumn(colHeights: IntArray): Int {
        var minHeight = Int.MAX_VALUE
        var column = 0
        colHeights.forEachIndexed { index, height ->
            if (height < minHeight) {
                minHeight = height
                column = index
            }
        }
        return column
    }
    
  4. 效果图:下面是我用该布局在自己写的一个应用中的使用情况。

posted @ 2021-09-14 10:22  SowHappy  阅读(641)  评论(0)    收藏  举报