【问题标题】:How to do Multiline chip group in Jetpack Compose?如何在 Jetpack Compose 中做 Multiline 芯片组?
【发布时间】:2025-12-26 16:05:09
【问题描述】:

所以,我创建了一个可组合的芯片并在 LazyRow 中使用它,如下所示:

LazyRow(
        modifier = modifier,
        horizontalArrangement = Arrangement.spacedBy(16.dp),
    ){
   items.forEach { it ->
            item {
                CustomChip(
                    item = it,
                    isSelected = it == currentItem,
                    onItemChanged = {
                        onItemChanged(it)
                    }
                )
            }
        }
}

但是,我想获得像上面提到的图像那样的布局。即,如果芯片数量达到屏幕末尾,则新芯片应进入新行。

【问题讨论】:

    标签: android android-studio kotlin android-jetpack android-jetpack-compose


    【解决方案1】:

    更新。现在你可以使用Accompanist FlowRow

    FlowRow(
        modifier = modifier,
        mainAxisSpacing = 16.dp,
        crossAxisSpacing = 16.dp,
    ) {
        items.forEach { it ->
            CustomChip(
                item = it,
                isSelected = it == currentItem,
                onItemChanged = {
                    onItemChanged(it)
                }
            )
        }
    }
    

    原始答案。如果您有兴趣自己构建类似的东西,可以使用Layout

    @Composable
    fun ChipVerticalGrid(
        modifier: Modifier = Modifier,
        spacing: Dp,
        content: @Composable () -> Unit
    ) {
        Layout(
            content = content,
            modifier = modifier
        ) { measurables, constraints ->
            var currentRow = 0
            var currentOrigin = IntOffset.Zero
            val spacingValue = spacing.toPx().toInt()
            val placeables = measurables.map { measurable ->
                val placeable = measurable.measure(constraints)
    
                if (currentOrigin.x > 0f && currentOrigin.x + placeable.width > constraints.maxWidth) {
                    currentRow += 1
                    currentOrigin = currentOrigin.copy(x = 0, y = currentOrigin.y + placeable.height + spacingValue)
                }
    
                placeable to currentOrigin.also {
                    currentOrigin = it.copy(x = it.x + placeable.width + spacingValue)
                }
            }
    
            layout(
                width = constraints.maxWidth,
                height = placeables.lastOrNull()?.run { first.height + second.y } ?: 0
            ) {
                placeables.forEach {
                    val (placeable, origin) = it
                    placeable.place(origin.x, origin.y)
                }
            }
        }
    }
    

    用法:

    val words = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
        .split(" ")
    ChipVerticalGrid(
        spacing = 7.dp,
        modifier = Modifier
            .padding(7.dp)
    ) {
        words.forEach { word ->
            Text(
                word,
                modifier = Modifier
                    .background(color = Color.Gray, shape = CircleShape)
                    .padding(vertical = 3.dp, horizontal = 5.dp)
            )
        }
    }
    

    结果:

    【讨论】:

    • 感谢这种方法。但两种解决方案都不支持可滚动性。
    • 好的:很容易得到。只需将.verticalScroll(scrollState) 添加到 flowLayout 的修饰符