You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 20:36:02