You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jetpack Compose中实现可变宽度的垂直交错网格?

实现Jetpack Compose自适应流式布局

你需要的是流式布局——让项的宽度根据自身文本内容自适应,一行放不下时自动换行,这和LazyVerticalStaggeredGrid固定列宽、LazyHorizontalStaggeredGrid横向滚动的特性不匹配,下面提供两种可行方案:

方案一:使用Accompanist FlowRow(推荐)

Accompanist库提供了现成的FlowRow组件,专门解决这种流式排列需求。

1. 添加依赖

在模块级build.gradle中引入FlowLayout依赖:

dependencies {
    implementation "com.google.accompanist:accompanist-flowlayout:<最新版本号>"
}

(注:可通过Google Maven仓库获取最新版本号,当前常用版本为0.32.0)

2. 实现代码

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.google.accompanist.flowlayout.FlowRow
import com.google.accompanist.flowlayout.MainAxisAlignment

@Composable
fun FlowTagList(tags: List<String>) {
    FlowRow(
        modifier = Modifier.padding(16.dp),
        mainAxisAlignment = MainAxisAlignment.Start,
        // 项之间的水平间距
        mainAxisSpacing = 8.dp,
        // 行之间的垂直间距
        crossAxisSpacing = 8.dp
    ) {
        tags.forEach { tag ->
            Text(
                text = tag,
                modifier = Modifier
                    .background(Color.LightGray, RoundedCornerShape(16.dp))
                    .padding(horizontal = 12.dp, vertical = 6.dp),
                color = Color.Black
            )
        }
    }
}

FlowRow会自动计算每行可容纳的项,超出后自动换行,每个子项的宽度完全由自身文本内容决定。

方案二:自定义流式布局(无第三方依赖)

如果不想引入外部库,可以基于Compose的Layout组件手动实现流式布局逻辑:

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.unit.dp

@Composable
fun CustomFlowRow(
    modifier: Modifier = Modifier,
    spacing: Dp = 8.dp,
    content: @Composable () -> Unit
) {
    Layout(
        modifier = modifier,
        content = content
    ) { measurables, constraints ->
        val spacingPx = spacing.toPx().toInt()
        var currentRowWidth = 0
        var currentRowHeight = 0
        val rows = mutableListOf<MutableList<Placeable>>()
        val rowHeights = mutableListOf<Int>()
        var currentRow = mutableListOf<Placeable>()

        measurables.forEach { measurable ->
            val placeable = measurable.measure(constraints)
            val placeableWidth = placeable.width

            // 当前行放不下新项时,换行
            if (currentRowWidth + placeableWidth + spacingPx > constraints.maxWidth) {
                rows.add(currentRow)
                rowHeights.add(currentRowHeight)
                currentRow = mutableListOf()
                currentRowWidth = 0
                currentRowHeight = 0
            }

            currentRow.add(placeable)
            currentRowWidth += placeableWidth + spacingPx
            currentRowHeight = maxOf(currentRowHeight, placeable.height)
        }

        // 添加最后一行
        if (currentRow.isNotEmpty()) {
            rows.add(currentRow)
            rowHeights.add(currentRowHeight)
        }

        // 计算总高度并布局子项
        val totalHeight = rowHeights.sum() + (rows.size - 1) * spacingPx
        layout(constraints.maxWidth, totalHeight) {
            var yPosition = 0
            rows.forEachIndexed { rowIndex, row ->
                var xPosition = 0
                row.forEach { placeable ->
                    placeable.placeRelative(xPosition, yPosition)
                    xPosition += placeable.width + spacingPx
                }
                yPosition += rowHeights[rowIndex] + spacingPx
            }
        }
    }
}

// 使用示例
@Composable
fun CustomFlowTagList(tags: List<String>) {
    CustomFlowRow(
        modifier = Modifier.padding(16.dp),
        spacing = 8.dp
    ) {
        tags.forEach { tag ->
            Text(
                text = tag,
                modifier = Modifier
                    .background(Color.LightGray, RoundedCornerShape(16.dp))
                    .padding(horizontal = 12.dp, vertical = 6.dp),
                color = Color.Black
            )
        }
    }
}

这个自定义组件通过手动测量每个子项的尺寸,计算每行可容纳的数量,最终实现流式排列效果,功能和FlowRow一致。

内容的提问来源于stack exchange,提问作者Jaimin Vashi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 06:45:31