Jetpack Compose:如何使 FlowRow 中的所有项目具有相同的高度

问题描述 投票:0回答:1

我有一些动态的

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()
时,代码显示的内容:

我真正想要的:

android-jetpack-compose height flowlayout
1个回答
0
投票

我尝试获取所有项目的高度,一旦它们全部显示,我找到最大高度并将其应用于所有项目。这是代码:

@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
}

预览:

© www.soinside.com 2019 - 2024. All rights reserved.