Jetpack Compose:Lazy Column重组时崩溃问题求助
问题根源
你遇到的崩溃是因为在LazyColumn内部嵌套了另一个完整的LazyColumn:点击展开时,HandleHistoryTodayChild直接调用PrepareOverViewScreen,而这个函数内部又包含Scaffold和LazyColumn,导致滚动组件嵌套,触发无限高度约束的异常。
解决方案
不需要嵌套整个屏幕,而是把展开/收起的状态提升到列表层级,在同一个LazyColumn中控制子项的显示。
1. 重构列表状态与渲染逻辑
将展开状态提升到DisplayOverViewScreen,统一管理所有头部的展开状态,然后在同一个LazyColumn中渲染头部和对应的子项:
@Composable fun DisplayOverViewScreen( modifier: Modifier = Modifier, overViewList: List<OverViewListItem> ) { // 用StateMap保存每个头部的展开状态,key为Header的类型 val expandedStates = remember { mutableStateMapOf<ItemType, Boolean>() } LazyColumn(modifier = modifier) { items(overViewList) { data -> when (data) { is OverViewHeaderItem -> { // 渲染头部,传递展开状态和点击回调 HeaderItem( overViewHeaderItem = data, isExpanded = expandedStates[data.listType] ?: false, onToggleExpand = { expandedStates[data.listType] = !(expandedStates[data.listType] ?: false) } ) // 如果当前头部展开,渲染对应的子项 if (expandedStates[data.listType] == true) { // 过滤出当前头部对应的子项(假设子项有parentType关联头部) val childItems = overViewList.filter { it is OverViewChildItem && it.parentType == data.listType } items(childItems) { childData -> ChildItem(childData as OverViewChildItem) } } } is OverViewChildItem -> { // 非展开状态下不渲染子项,避免冗余 if (expandedStates[data.parentType] == true) { ChildItem(data) } } } } } }
2. 修改HeaderItem组件
移除嵌套屏幕的逻辑,只负责头部UI和展开/收起的交互:
@Composable fun HeaderItem( overViewHeaderItem: OverViewHeaderItem, isExpanded: Boolean, onToggleExpand: () -> Unit ) { var angle by remember { mutableStateOf(0f) } // 根据展开状态自动旋转图标 LaunchedEffect(isExpanded) { angle = if (isExpanded) 180f else 0f } when (overViewHeaderItem.listType) { ItemType.IN_PROGRESS_HEADER -> { Column( modifier = Modifier .fillMaxWidth() .height(50.dp) .background(Color(0xffdc8633)), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.Start ) { Text( text = "In Progress", color = Color.White, modifier = Modifier.padding(start = 16.dp) ) } } ItemType.HISTORY_TODAY_HEADER -> { Column( modifier = Modifier .fillMaxWidth() .height(50.dp) .background(Color(0xffd7d7d7)), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.Start ) { Text( text = stringResource(R.string.history_label), color = Color.Black, modifier = Modifier.padding(start = 16.dp) ) } } else -> { Row( modifier = Modifier .fillMaxWidth() .height(50.dp) .background(Color(0xffd7d7d7)) .clickable { onToggleExpand() }, // 整个头部区域可点击 horizontalArrangement = Arrangement.Start, verticalAlignment = Alignment.CenterVertically ) { Text( text = stringResource(R.string.history_yesterday), color = Color.Black, modifier = Modifier.padding(start = 16.dp) ) Spacer(Modifier.weight(1f)) Image( painter = painterResource(id = R.drawable.ic_expand_more), modifier = Modifier .padding(end = 5.dp) .rotate(angle), contentDescription = "展开/收起图标" ) } } } }
3. 移除冗余函数
删除HandleHistoryTodayChild函数,因为现在不需要嵌套整个屏幕来实现展开效果。
关键说明
Compose中禁止滚动组件(如LazyColumn、Column(Modifier.verticalScroll()))嵌套,因为内部滚动组件会收到父级传递的无限高度约束,导致测量异常。正确的做法是在同一个滚动容器内,通过状态控制子项的显示/隐藏。
内容的提问来源于stack exchange,提问作者Android_programmer_office
相关产品推荐
相关产品推荐

