Jetpack Compose 中如何将 sheetPeekHeight 设为内部项的指定高度比例
实现方案
核心思路:由于Compose声明式UI的渲染特性,无法在初始化阶段直接拿到未渲染组件的尺寸,因此需要通过布局回调监听首项Card渲染后的实际高度,做单位换算后动态设置sheetPeekHeight,具体实现步骤如下:
- 第一步:声明可观测状态存储高度数值,同时引入密度实例做单位转换
// 存储首项Card的实际高度,单位dp var firstCardHeight by remember { mutableStateOf(0.dp) } // 最终的sheet弹出高度,设置40%的比例,可添加兜底默认值避免布局闪烁 val sheetPeekHeight by remember { derivedStateOf { if (firstCardHeight == 0.dp) 64.dp else firstCardHeight * 0.4f } } val density = LocalDensity.current
- 第二步:修改列表遍历逻辑,给首项Card添加布局尺寸监听
把原来的items(data.items)替换为带索引的itemsIndexed,仅对首项添加高度监听逻辑:
LazyColumn( state = listState, contentPadding = PaddingValues(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp), ) { itemsIndexed(data.items) { index, item -> Card( modifier = Modifier .fillMaxWidth() // 仅对第一个Card添加高度监听 .run { if (index == 0) { this.onGloballyPositioned { layoutCoordinates -> // 将px单位的渲染高度转换为dp val heightDp = with(density) { layoutCoordinates.size.height.toDp() } // 仅高度变化时更新状态,避免触发不必要的重组 if (firstCardHeight != heightDp) { firstCardHeight = heightDp } } } else this } ) { Column { Text(text = item.title) Text(text = item.subtitle) Spacer(modifier = Modifier.height(8.dp)) Text(text = item.image) } } } }
- 第三步:将计算好的高度状态赋值给
BottomSheetScaffold对应参数
BottomSheetScaffold( sheetContent = { /* 上述修改后的LazyColumn代码 */ }, sheetPeekHeight = sheetPeekHeight ) { // 页面主体内容逻辑 }
适配提示:如果数据源
data.items可能为空,可根据业务需求调整sheetPeekHeight的兜底默认值,避免空列表场景下底部弹出条高度异常。
内容的提问来源于stack exchange,提问作者Dallas
相关产品推荐
相关产品推荐

