答案 0 :(得分:11)
您可以使用FlowRow
来实现。它会水平渲染其子级(例如Row
),如果子级不适合现有的行,还会通过移动到新行来对其进行包装。
要很好地处理很长的字符串(它们本身不能放入一行),可以在overflow = TextOverflow.Ellipsis
上设置maxLines = 1
和Text
。
@Composable
fun HashTagList(hashTags: List<String>) {
Box(modifier = Modifier.padding(8.dp)) {
FlowRow(
mainAxisAlignment = MainAxisAlignment.Center,
mainAxisSize = SizeMode.Expand,
crossAxisSpacing = 12.dp,
mainAxisSpacing = 8.dp
) {
hashTags.forEach { hashTag ->
Text(
text = hashTag,
modifier = Modifier.drawBackground(
color = colorForHashTag(hashTag),
shape = RoundedCornerShape(4.dp)
).padding(8.dp),
overflow = TextOverflow.Ellipsis,
maxLines = 1
)
}
}
}
}
答案 1 :(得分:1)
对于那些正在寻找也接受 Alignment.Vertical
来控制具有较小高度的项目的对齐方式的实现的人,这里是 Valeriy 答案的修改版本:
@Composable
fun FlowRow(
modifier: Modifier = Modifier,
alignment: Alignment.Horizontal = Alignment.Start,
verticalAlignment: Alignment.Vertical = Alignment.CenterVertically,
verticalGap: Dp = 0.dp,
horizontalGap: Dp = 0.dp,
content: @Composable () -> Unit
) = Layout(content, modifier) { measurables, constraints ->
val hGapPx = horizontalGap.roundToPx()
val vGapPx = verticalGap.roundToPx()
val rows = mutableListOf<MeasuredRow>()
val itemConstraints = constraints.copy(minWidth = 0)
for (measurable in measurables) {
val lastRow = rows.lastOrNull()
val placeable = measurable.measure(itemConstraints)
if (lastRow != null && lastRow.width + hGapPx + placeable.width <= constraints.maxWidth) {
lastRow.items.add(placeable)
lastRow.width += hGapPx + placeable.width
lastRow.height = max(lastRow.height, placeable.height)
} else {
val nextRow = MeasuredRow(
items = mutableListOf(placeable),
width = placeable.width,
height = placeable.height
)
rows.add(nextRow)
}
}
val width = rows.maxOfOrNull { row -> row.width } ?: 0
val height = rows.sumBy { row -> row.height } + max(vGapPx.times(rows.size - 1), 0)
val coercedWidth = width.coerceIn(constraints.minWidth, constraints.maxWidth)
val coercedHeight = height.coerceIn(constraints.minHeight, constraints.maxHeight)
layout(coercedWidth, coercedHeight) {
var y = 0
for (row in rows) {
var x = when(alignment) {
Alignment.Start -> 0
Alignment.CenterHorizontally -> (coercedWidth - row.width) / 2
Alignment.End -> coercedWidth - row.width
else -> throw Exception("unsupported alignment")
}
for (item in row.items) {
var localY = 0
if (item.height < row.height) {
localY = when (verticalAlignment) {
Alignment.Start -> y
Alignment.CenterVertically -> y + ((row.height + vGapPx) / 2 - item.height / 2)
Alignment.End -> y + row.height
else -> throw Exception("unsupported alignment")
}
} else localY = y
item.place(x, localY)
x += item.width + hGapPx
}
y += row.height + vGapPx
}
}
}
private data class MeasuredRow(
val items: MutableList<Placeable>,
var width: Int,
var height: Int
)
答案 2 :(得分:0)
伴奏中的流布局正是您所需要的
您可以在此处找到文档:https://google.github.io/accompanist/flowlayout/
具体来说,FlowRow
将允许您在示例中实现您想要的