Jetpack Compose BottomSheetScaffold底页内容为空时总是展开且点击报错问题
问题根因
BottomSheetScaffold 内部会根据 sheetContent 的实际高度计算 Expanded、Collapsed 两个状态对应的锚点值。当 bottomSheet() 无内容高度为0时,框架无法生成 Expanded 状态对应的锚点,此时对底部表做展开/折叠操作就会抛出java.lang.IllegalArgumentException: The target value must have an associated anchor.异常;同时因为状态判断逻辑没有过滤空内容场景,会导致Scrim遮罩错误显示。
解决方案
分三步实现修复:
- 第一步:新增底部表内容有效性判断状态,监听 sheetContent 实际高度
// 标记底部表是否有有效内容(高度>0) val hasValidBottomSheetContent = remember { mutableStateOf(false) } val coroutineScope = rememberCoroutineScope()
修改sheetContent的代码,增加高度测量逻辑:
sheetContent = { Box( Modifier.onGloballyPositioned { coordinates -> hasValidBottomSheetContent.value = coordinates.size.height > 0 // 空内容时主动重置状态为折叠,避免状态异常 if (!hasValidBottomSheetContent.value && bottomSheetState.bottomSheetState.isExpanded) { coroutineScope.launch { bottomSheetState.bottomSheetState.collapse() } } } ) { bottomSheet() } }
- 第二步:修改Scrim的可见性判断逻辑,增加内容有效性校验
Scrim( color = Primary, alpha = bottomSheetState.currentFraction * 0.5f, onDismiss = { // 操作前先判断是否有有效内容,避免空内容时操作抛异常 if (hasValidBottomSheetContent.value) { coroutineScope.launch { bottomSheetState.bottomSheetState.collapse() } } }, // 新增内容有效性判断条件 visible = hasValidBottomSheetContent.value && bottomSheetState.bottomSheetState.targetValue != BottomSheetValue.Collapsed && bottomSheetState.bottomSheetState.currentValue != BottomSheetValue.Collapsed )
- 第三步:所有主动触发底部表展开的位置,都增加内容有效性校验
// 示例:触发展开前先判断 fun expandBottomSheet() { if (hasValidBottomSheetContent.value) { coroutineScope.launch { bottomSheetState.bottomSheetState.expand() } } }
可选优化方案
如果你的业务逻辑本身是按条件控制底部表是否需要展示,可以直接在传入bottomSheet参数时做判空,无内容时直接传入0高度占位,从源头避免空内容场景:
BottomSheetScaffold( // 其他参数保持不变 sheetContent = { if (needShowBottomSheet) { // 替换为你的业务判断条件 bottomSheet() } else { Spacer(modifier = Modifier.height(0.dp)) } } )
内容的提问来源于stack exchange,提问作者Vahid
相关产品推荐
相关产品推荐

