我有一些动态的
Text
可组合项放在 FlowRow
中,但我似乎无法让它们具有相同的高度。使用普通的 Row
,您可以在行上使用 .height(Intrinsic.Min)
与子项上的 .fillMaxHeight()
结合使用,但我无法将其与 FlowRow
一起使用。
Flow Layouts 的文档讨论了 FlowRow 中不同高度的项目的对齐,但没有提到如何使它们全部具有相同的高度。也许我错过了什么?
这是一个代码示例。我注释掉了我尝试内在高度和 fillMaxHeight 的地方:
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@OptIn(ExperimentalLayoutApi::class)
@Preview(showBackground = true, widthDp = 400)
@Composable
private fun FlowRowPreview() {
val textModifier = Modifier.width(185.dp).background(Color.Red)//.fillMaxHeight()
FlowRow(
horizontalArrangement = Arrangement.Absolute.SpaceBetween,
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier//.height(IntrinsicSize.Min)
) {
Text(modifier = textModifier, text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam")
Text(modifier = textModifier, text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit")
Text(modifier = textModifier, text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit")
Text(modifier = textModifier, text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit")
}
}
当我取消注释
.height(IntrinsicSize.Min)
和 .fillMaxHeight()
时,代码显示的内容:
我尝试获取所有项目的高度,一旦它们全部显示,我找到最大高度并将其应用于所有项目。这是代码:
@OptIn(ExperimentalLayoutApi::class)
@Composable
private fun FlowRowPreview() {
val lorem = "" +
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, " +
"sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
"Ut enim ad minim"
// Container to store all heights
val heightsMap = mutableMapOf<Int, Int>() // map instead of list to avoid side effects
// Will recompose views once the value is changed
val finalHeightBlock = remember { mutableIntStateOf(0) } // final height to set
// Data we are going to
val data = listOf(
lorem,
lorem.substring(0, lorem.length / 2),
lorem.substring(0, lorem.length / 2),
lorem.substring(0, lorem.length / 2),
).mapIndexed { index, text ->
index to text
}
// Block for storing heights and calling recompose once all heights are stored
val reportHeight: (Int, Int) -> Unit = { index, height ->
heightsMap[index] = height
if (heightsMap.size == data.size) {
finalHeightBlock.intValue = heightsMap.maxOf { it.value }
}
}
FlowRow(
horizontalArrangement = Arrangement.Absolute.SpaceBetween,
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
data.forEach {
FlowText(it.second, it.first, finalHeightBlock, reportHeight)
}
}
}
@Composable
private fun FlowText(
lorem: String,
index: Int,
height: MutableIntState,
reportHeight: (Int, Int) -> Unit,
) {
val modifier = if (height.intValue > 0) {
Modifier
.width(185.dp)
.height(height.intValue.pxToDp())
.background(Color.Red)
} else {
Modifier
.width(185.dp)
.wrapContentHeight()
.background(Color.Red)
.onGloballyPositioned { it ->
reportHeight(index, it.size.height)
}
}
Text(
modifier = modifier,
text = lorem
)
}
@Composable
fun Int.pxToDp(): Dp {
val density = LocalDensity.current.density
return (this / density).dp
}