You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose LazyVerticalGrid实现动态子项同高(不设固定高度)

解决LazyVerticalGrid每行网格项高度统一问题

我需要实现一个采用GridCells.Fixed(2)的LazyVerticalGrid,网格项会根据数据条件显示不同组件(比如数据不可用时隐藏对应组件)。要求每行的两个网格项高度一致,取该行中较高项的高度,且不想为网格项设置固定高度。

当前效果

当前状态

预期效果(示例为设置固定高度后的效果)

预期效果

基础实现代码

@Composable
fun DynamicHeightGrid(items: List = listOf(item1, item2, item3, item4, item5)) {
    LazyVerticalGrid(
        columns = GridCells.Fixed(2),
        modifier = Modifier
            .padding(16.dp)
    ) {
        itemsIndexed(items) { index, item ->
            GridItem(item)
        }
    }
}

@Composable
fun GridItem(
    content: RandomItems,
) {
    Card(
        modifier = Modifier
            .padding(4.dp)
            .fillMaxWidth()
    ) {
        Column(
            modifier = Modifier
                .padding(4.dp)
        ) {
            with(content) {
                Text(text = title!!, fontSize = 20.sp, maxLines = 3)
                Spacer(modifier = Modifier.height(2.dp))

                Text(text = " Price: $price!!", fontSize = 24.sp)

                value?.let {
                    Text(text = value, fontSize = 14.sp)
                }

                Text(text = shortDesc!!, fontSize = 14.sp)

                passion?.let {
                    Text(text = passion, fontSize = 14.sp)
                }

                newValue?.let {
                    Text(text = newValue, fontSize = 14.sp)
                }

                Spacer(modifier = Modifier.height(10.dp))
                if (isRequired == true) {
                    Button(
                        onClick = { },
                        modifier = Modifier
                            .height(20.dp)
                            .fillMaxWidth()
                            .background(Color.Red)
                    ) {
                        Text(
                            color = Color.White,
                            text = "Get New value"
                        )
                    }
                }
            }
        }
    }
}

已尝试的方案

  • 调整LazyVerticalGrid网格项高度的相关方案
  • Jetpack Compose中让Row内所有项高度一致的方案

解决方案:按行分组处理,使用Row实现高度同步

由于LazyVerticalGrid本身不支持自动对齐每行项的高度,我们可以将数据按行分组,用Row包裹每行的网格项,借助布局特性实现高度统一。

修改后的代码

@Composable
fun DynamicHeightGrid(items: List<RandomItems> = listOf(item1, item2, item3, item4, item5)) {
    LazyColumn(
        modifier = Modifier
            .padding(16.dp)
    ) {
        // 将数据按每2个一组拆分,最后一组可能仅含1个元素
        items.chunked(2).forEach { rowItems ->
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(IntrinsicSize.Min), // 让Row高度适配该行最高的子项
                horizontalArrangement = Arrangement.spacedBy(8.dp)
            ) {
                rowItems.forEach { item ->
                    GridItem(item)
                        .modifier
                        .weight(1f) // 让两个网格项均分宽度
                }
                // 最后一行只有1个元素时,添加占位符保持布局对称(可选)
                if (rowItems.size == 1) {
                    Spacer(modifier = Modifier.weight(1f))
                }
            }
            Spacer(modifier = Modifier.height(8.dp)) // 行之间的间距
        }
    }
}

// 调整GridItem实现,移除fillMaxWidth(由weight控制宽度)
@Composable
fun GridItem(
    content: RandomItems,
): @Composable () -> Unit {
    return {
        Card(
            modifier = Modifier
                .padding(4.dp)
        ) {
            Column(
                modifier = Modifier
                    .padding(4.dp)
            ) {
                with(content) {
                    Text(text = title!!, fontSize = 20.sp, maxLines = 3)
                    Spacer(modifier = Modifier.height(2.dp))

                    Text(text = " Price: $price!!", fontSize = 24.sp)

                    value?.let {
                        Text(text = value, fontSize = 14.sp)
                    }

                    Text(text = shortDesc!!, fontSize = 14.sp)

                    passion?.let {
                        Text(text = passion, fontSize = 14.sp)
                    }

                    newValue?.let {
                        Text(text = newValue, fontSize = 14.sp)
                    }

                    Spacer(modifier = Modifier.height(10.dp))
                    if (isRequired == true) {
                        Button(
                            onClick = { },
                            modifier = Modifier
                                .height(20.dp)
                                .fillMaxWidth()
                                .background(Color.Red)
                        ) {
                            Text(
                                color = Color.White,
                                text = "Get New value"
                            )
                        }
                    }
                }
            }
        }
    }
}

方案说明

  1. 用LazyColumn替代LazyVerticalGrid,将数据按每2个一组拆分,每行对应一个Row组件
  2. Row设置height(IntrinsicSize.Min),让Row的高度自动适配该行中最高的子项
  3. 每个网格项添加Modifier.weight(1f),实现两个项的宽度均分
  4. 最后一行若只有1个元素,可添加占位符保持布局对称(根据需求选择是否保留)

这种方式无需设置固定高度,能自动让每行的两个网格项高度统一,完全符合需求。


内容的提问来源于stack exchange,提问作者Sudarshan Bhatt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 18:05:07