如何调平 LazyVerticalGrid 中项目的高度?

How to level the height of items in LazyVerticalGrid?

我正在使用 LazyVerticalGrid 来显示项目列表。

LazyVerticalGrid(
            cells = GridCells.Fixed(2),
            modifier = Modifier.fillMaxSize(),
            state = listState,
            content = {
                    Box(modifier = boxModifier) {
                        ProductItemView(
                            item = items[index]
                        )
                    }
                }
            }
        )

有时我的一些物品比旁边的物品高(附件)

如何调整所有项目的高度?或者我应该使用 VerticalGrid() 以外的东西吗?

发生的事情是任何一项的文本大于一行,它会展开

为了保持统一的高度,您必须为每个 child Box 设置一个最小高度,为此,您可以使用下面的 Modifier

//Adjust 200.dp as your requirement
Box(modifier = Modifier.height(200.dp))

这样,无论内容 length/size 是什么,每个框都将具有相同的高度。

如果您为可组合项提供固定高度,您最终可能会得到不显示子可组合项某些部分的可组合项,在您的情况下,它可能是 Text 可组合项。

第一个简单的方法是设置最小高度 Modifier.heightIn(min = 200.dp),这可能会使可组合项低于或高于 space,具体取决于您的 Box 对齐方式,如果您的可组合项高于 [=24] =] 它会和你现在有同样的效果,所以它不是或者添加任何固定高度是不够的。

更好的方法是使用 onTextLayout 获取文本的行数和高度,以添加较少的行数作为填充

@Composable
fun GridSnackCardWithTitle(
    modifier: Modifier = Modifier,
    snack: Snack,
) {
    Column(
        modifier = modifier
            .heightIn(min = 200.dp)
            .shadow(1.dp, shape = RoundedCornerShape(5.dp))
            .background(Color.White),

        ) {

        val density = LocalDensity.current.density

        Image(
            contentScale = ContentScale.None,
            modifier = Modifier
                .fillMaxWidth()
                .aspectRatio(1f)
                .clip(RoundedCornerShape(8.dp))
                .clickable { },
            painter = rememberImagePainter(
                data = snack.imageUrl,
                builder = {
                    placeholder(drawableResId = R.drawable.placeholder)
                }
            ),
            contentDescription = null
        )

        Spacer(modifier = Modifier.height(4.dp))
        var padding by remember { mutableStateOf(0.dp) }
        Text(
            modifier = Modifier.padding(start = 4.dp, end = 4.dp, bottom = padding),
            text = "Snack ${snack.name}",
            fontSize = 20.sp,
            onTextLayout = {
                val lineCount = it.lineCount
                val height = (it.size.height / density).dp

                println("lineCount: $lineCount, Height: $height")
                padding = if (lineCount > 1) 0.dp else height
            }
        )
        
    }
}

结果

通常这样的问题是通过添加 Modifier.fillMaxHeight 到包含项,和 Modifier.height(IntrinsicSize.Max) 到容器来解决的。

问题是在这种情况下我们无法访问容器 Modifier:在 Compose 1.1.* 中有一个 Row源代码,但我们不能将修饰符传递给它,在 1.2.* 中根本没有 Row.

我认为这样的要求是公平的,但现在你可以自己在LazyColumn:

val columnsCount = 2
val itemsCount = 10
LazyColumn(
    modifier = Modifier.fillMaxSize()
) {
    items((itemsCount + 1) / columnsCount) { i ->
        Row(Modifier.height(IntrinsicSize.Max)) {
            for (j in 0 until columnsCount) {
                val index = i * columnsCount + j
                if (index < itemsCount) {
                    Text(
                        LoremIpsum(index).values.first(),
                        modifier = Modifier
                            .fillMaxHeight()
                            .weight(1f)
                            .background(
                                when (index % 3) {
                                    0 -> Color.LightGray
                                    1 -> Color.DarkGray
                                    else -> Color.Gray
                                }
                            )
                    )
                } else {
                    Spacer(Modifier.weight(1f))
                }
            }
        }
    }
}