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

Jetpack Compose页面添加滚动报错:垂直滚动组件无限高度不允许

解决嵌套滚动组件的无限高度报错问题

问题原因

外层Column添加verticalScroll后,会给子组件传递无限高度约束,而LazyColumn必须基于确定的高度才能正常渲染,因此触发报错。要实现整页滚动,正确的做法是用LazyColumn作为整个页面的根容器,统一处理滚动逻辑,内部不再嵌套滚动组件。

修改方案

1. 重构主组件ContactDetails

将外层的Column替换为LazyColumn,移除verticalScroll修饰符,把所有静态内容和列表模块放在LazyColumn的item块中:

@Composable
fun ContactDetails(contactViewModel: ContactViewModel, contactId: String?) {
    val contact = contactViewModel.getContactById(contactId)
    LazyColumn(
        modifier = Modifier.fillMaxWidth(),
        horizontalAlignment = Alignment.Start
    ) {
        // 头部卡片区域
        item {
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(350.dp)
            ) {
                Card(modifier = Modifier.fillMaxWidth()) {
                    if (contact[0].image != null) {
                        Image(
                            painter = rememberImagePainter(data = contact[0].image),
                            contentDescription = "联系人头像",
                            modifier = Modifier.fillMaxWidth(),
                            contentScale = ContentScale.Crop
                        )
                    } else {
                        Box(
                            modifier = Modifier
                                .fillMaxHeight()
                                .fillMaxWidth()
                                .background(color = Color.Magenta),
                            contentAlignment = Alignment.Center,
                        ) {
                            Text(
                                text = contact[0].first_name[0].toString(),
                                fontSize = 26.sp,
                                fontWeight = FontWeight.Bold
                            )
                        }
                    }
                    Box(
                        modifier = Modifier
                            .fillMaxWidth()
                            .fillMaxHeight(),
                        contentAlignment = Alignment.BottomStart
                    ) {
                        Text(
                            text = "${contact.first().first_name} ${contact.first().last_name}",
                            color = Color.White,
                            style = MaterialTheme.typography.h4,
                            fontWeight = FontWeight.Bold
                        )
                    }
                }
            }

            Divider(
                color = Color.LightGray,
                thickness = 2.dp,
            )
        }

        // 电话列表模块
        item {
            phoneCard(contact = contact.first(), contactViewModel)
        }

        // 邮箱列表模块
        item {
            emailCard(contact = contact.first(), contactViewModel)
        }
    }
}

2. 修改子组件phoneCard和emailCard

移除内部的LazyColumn,换成普通Column,因为滚动逻辑已经由外层LazyColumn处理:

@Composable
fun phoneCard(contact: Contact, contactViewModel: ContactViewModel) {
    val phoneList = contactViewModel.getPhoneListByContactId(contact.id)
    Column {
        Row(modifier = Modifier.padding(10.dp)) {
            Icon(imageVector = Icons.Default.Phone, contentDescription = "电话图标")
            Text(
                text = "电话:",
                modifier = Modifier.padding(start = 10.dp),
                textAlign = TextAlign.Center,
                style = MaterialTheme.typography.h6,
                fontWeight = FontWeight.Bold
            )
        }
        phoneList.forEach {
            Row(modifier = Modifier.padding(10.dp)) {
                Text(text = "${it.type}: ", fontWeight = FontWeight.Bold)
                Text(text = it.number)
            }
        }
    }
}

@Composable
fun emailCard(contact: Contact, contactViewModel: ContactViewModel) {
    val emailList = contactViewModel.getEmailListByContactId(contact.id)
    Column {
        Row(modifier = Modifier.padding(10.dp)) {
            Icon(imageVector = Icons.Default.Email, contentDescription = "邮箱图标")
            Text(
                text = "邮箱:",
                modifier = Modifier.padding(start = 10.dp),
                textAlign = TextAlign.Center,
                style = MaterialTheme.typography.h6,
                fontWeight = FontWeight.Bold
            )
        }
        emailList.forEach {
            Row(modifier = Modifier.padding(10.dp)) {
                Text(text = "${it.type}: ", fontWeight = FontWeight.Bold)
                Text(text = it.address)
            }
        }
    }
}

原理说明

LazyColumn会根据内部内容的总高度自动处理滚动,同时给每个子项传递合理的约束条件。将所有内容放在同一个LazyColumn中,既实现了整页滚动,又避免了嵌套滚动组件带来的约束冲突问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 04:10:13