Jetpack Compose中如何禁用BottomSheet外部点击 仅允许内部按钮关闭
Jetpack Compose BottomSheet 锁定禁止外部关闭实现方案
你可以通过拦截状态变更+屏蔽外部区域点击两步实现需求,修改后的代码如下:
@ExperimentalMaterialApi @Composable fun BottomSheet( modifier: Modifier = Modifier, composable: @Composable () -> Unit, scope: CoroutineScope ) { // 新增锁定状态:true代表禁止关闭,false允许关闭 val isSheetLocked = remember { mutableStateOf(true) } val bottomSheetScaffoldState = rememberBottomSheetScaffoldState( bottomSheetState = BottomSheetState( initialValue = BottomSheetValue.Expanded, // 拦截状态变更,锁定时不允许切换为折叠状态 confirmStateChange = { newState -> if (isSheetLocked.value) { newState != BottomSheetValue.Collapsed } else true } ) ) BottomSheetScaffold( scaffoldState = bottomSheetScaffoldState, sheetContent = { Column( Modifier .fillMaxWidth() .height(200.dp) .padding(8.dp), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { Button(colors = ButtonDefaults.buttonColors( backgroundColor = AppColor.brandColor.BLUE_DE_FRANCE, contentColor = AppColor.neutralColor.DOCTOR ), shape = RoundedCornerShape(small), onClick = { scope.launch { // 点击内部按钮先解锁,再执行关闭 isSheetLocked.value = false bottomSheetScaffoldState.bottomSheetState.collapse() } }) { Text("关闭按钮") } } }, sheetPeekHeight = 0.dp, sheetShape = RoundedCornerShape(topEnd = medium, topStart = medium) ) { // 给外部内容区域加点击拦截,锁定时消费所有点击事件不传递给下层的谷歌地图 Box( Modifier .fillMaxSize() .clickable(enabled = isSheetLocked.value, indication = null, interactionSource = remember { MutableInteractionSource() }) { // 空实现,消费点击事件 } ) { composable() } } }
实现逻辑说明
confirmStateChange回调会在BottomSheet要变更状态前触发,锁定状态下直接拒绝所有折叠操作,同时也会禁止下滑关闭手势- 外部内容区域加无视觉效果的点击拦截,锁定状态下所有点击外部的操作都会被消费,不会触发谷歌地图的交互逻辑
- 点击内部按钮时先修改锁定状态为false,再执行关闭操作,保证关闭逻辑正常执行
内容的提问来源于stack exchange,提问作者Saeed Noshadi
相关产品推荐
相关产品推荐

