Jetpack Compose:如何让父组件尺寸适配首个子组件后固定不变
解决Compose中Box保持第一个子组件尺寸的问题
要让Box在第一个子组件隐藏后仍保持其尺寸,核心思路是记录第一个子组件显示时的尺寸,并将该尺寸绑定到Box上,具体实现如下:
方案代码
@Composable fun YourComponent( modifier: Modifier = Modifier, bgColor: Color, buttonColor: Color, componentVisible1: Boolean, component2Visible: Boolean, onClicked: () -> Unit, enabled: Boolean ) { // 保存Button的尺寸状态 val buttonSize = remember { mutableStateOf(IntSize.Zero) } Box( modifier = modifier .run { // 如果已记录Button尺寸,就用该尺寸固定Box大小;否则用Button的默认约束 if (buttonSize.value != IntSize.Zero) { size(buttonSize.value.width.dp, buttonSize.value.height.dp) } else { widthIn(min = 144.dp).height(48.dp) } } .background(bgColor), contentAlignment = Alignment.Center ) { if (componentVisible1) { Button( modifier = Modifier .height(48.dp) .widthIn(144.dp) .onSizeChanged { buttonSize.value = it }, // 记录Button实际渲染尺寸 onClick = onClicked, enabled = enabled ) { Text(text = "text1") } } if (component2Visible) { CircularProgressIndicator( modifier = Modifier .size(24.dp) .background(buttonColor, CircleShape) .padding(2.dp), strokeWidth = 2.dp ) } } }
原理说明
- 尺寸记录:通过
Modifier.onSizeChanged监听Button的实际渲染尺寸,将其保存到remember维护的状态中,确保配置变更时尺寸不会丢失。 - Box尺寸绑定:Box的
modifier根据已记录的尺寸动态设置自身大小——当Button显示过一次后,即使后续隐藏,Box仍会使用之前记录的尺寸,避免缩小。 - 初始状态兼容:未记录尺寸前,给Box设置与Button一致的
widthIn(min=144.dp).height(48.dp),保证初始布局和Button显示时的尺寸一致,避免视觉闪烁。
备选简化方案(适合简单场景)
如果不介意隐藏的Button仍参与布局计算,可以直接用Modifier.alpha(0f)替代if判断隐藏Button,这样Box会始终保持Button的尺寸:
Box( modifier = modifier.background(bgColor), contentAlignment = Alignment.Center ) { Button( modifier = Modifier .height(48.dp) .widthIn(144.dp) .alpha(if (componentVisible1) 1f else 0f), // 仅隐藏视觉,保留布局空间 onClick = onClicked, enabled = enabled, interactionSource = remember { MutableInteractionSource() }, // 隐藏后不响应交互 indication = null ) { Text(text = "text1") } if (component2Visible) { CircularProgressIndicator( modifier = Modifier .size(24.dp) .background(buttonColor, CircleShape) .padding(2.dp), strokeWidth = 2.dp ) } }
注意:这个方案需要给Button添加interactionSource和indication = null,避免隐藏后仍能响应点击事件。
内容的提问来源于stack exchange,提问作者Androidew1267
相关产品推荐
相关产品推荐

