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

Jetpack Compose:如何在可滚动Column内实现含列表的Card?

解决Jetpack Compose嵌套滚动无限高度约束错误

错误提示“Vertically scrollable component was measured with an infinity maximum height constraints”的核心原因是:外层使用了可滚动容器(如Box(Modifier.verticalScroll())),它会给子元素传递无限高度的约束;当内部再嵌套另一个可滚动组件(如LazyColumn)时,后者无法确定自身的高度范围,从而触发错误。

关于拆分Card的可行性

将Card拆分为顶部、内容、底部三部分的方案完全可行。这种模块化拆分能让组件结构更清晰,便于后续维护和扩展,比如单独复用标题或底部组件。但要注意:如果内容部分是长列表,仅拆分结构还不够,需要配合滚动机制优化(见下文方案),否则仍可能出现性能问题或约束冲突。

推荐解决方法

1. 统一使用LazyColumn作为外层容器(最优解)

替换外层的Box+verticalScroll为LazyColumn,利用其按需加载特性,同时让所有滚动组件获得正确的高度约束。页面内的所有元素(Header、Card等)都作为LazyColumn的item添加,Card内的长列表也用LazyColumn实现:

fun RecipeDetailsApp() {
    val data = dummyRecipes[0]
    
    LazyColumn(
        modifier = Modifier.fillMaxWidth(),
        contentPadding = PaddingValues(bottom = 16.dp)
    ) {
        item {
            Header(photoUrl = data.photoUrl)
        }
        item {
            Column(
                modifier = Modifier
                    .padding(horizontal = 16.dp)
                    .offset(y = (-170).dp),
                verticalArrangement = Arrangement.spacedBy(16.dp),
            ) {
                TitleRow(data)
                NutritionFactsRow(data = data.nutrition)
                IngredientsRow(data.ingredients)
            }
        }
    }
}

@Composable
fun IngredientsRow(ingredients: List<String>) {
    ElevatedCard(
        modifier = Modifier.fillMaxWidth(),
        colors = CardDefaults.elevatedCardColors(
            containerColor = MaterialTheme.colorScheme.background
        ),
    ) {
        Column(
            modifier = Modifier
                .padding(horizontal = 24.dp, vertical = 16.dp)
                .fillMaxWidth()
        ) {
            SectionText(title = "Ingredients", modifier = Modifier)
            LazyColumn(
                modifier = Modifier.fillMaxWidth(),
                verticalArrangement = Arrangement.spacedBy(8.dp),
                contentPadding = PaddingValues(top = 8.dp)
            ) {
                items(ingredients) { item ->
                    Text(
                        text = item,
                        style = MaterialTheme.typography.bodyMedium
                    )
                }
            }
        }
    }
}

2. 给内部滚动组件指定明确高度(适合短列表场景)

如果必须保留外层的verticalScroll,可以给Card内的内容容器添加最大高度约束,让内部滚动组件能确定自身高度范围:

fun IngredientsRow(ingredients: List<String>) {
    ElevatedCard(
        modifier = Modifier.fillMaxWidth(),
        colors = CardDefaults.elevatedCardColors(
            containerColor = MaterialTheme.colorScheme.background
        ),
    ) {
        Column(
            modifier = Modifier
                .padding(horizontal = 24.dp, vertical = 16.dp)
                .fillMaxWidth()
        ) {
            SectionText(title = "Ingredients", modifier = Modifier)
            Box(
                modifier = Modifier
                    .fillMaxWidth()
                    .heightIn(max = 300.dp)
                    .verticalScroll(rememberScrollState())
            ) {
                Column(
                    modifier = Modifier.fillMaxWidth(),
                    verticalArrangement = Arrangement.spacedBy(8.dp),
                ) {
                    ingredients.forEach { item ->
                        Text(
                            text = item,
                            modifier = Modifier.padding(top = 8.dp),
                            style = MaterialTheme.typography.bodyMedium
                        )
                    }
                }
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 10:25:03