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

Jetpack Compose中ModalBottomSheet自定义显示行为问题求助

解决Jetpack Compose ModalBottomSheet初始70%高度+宽度动态变化问题

你的问题核心是未正确配置ModalBottomSheet的部分展开比例,且手动控制内容高度导致状态切换异常。以下是完全匹配需求的修正实现:

核心修改点

  • 自定义partiallyExpandedRatio为0.7f,让部分展开状态直接对应屏幕70%高度
  • 根据sheet状态动态设置内容左右内边距,实现初始8.dp边距、全屏时无内边距
  • 优化状态切换逻辑,打开时直接进入部分展开状态,避免中间过渡异常

修正代码

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ScaffoldWithBottomSheet() {
    // 配置部分展开比例为屏幕高度的70%
    val sheetState = rememberModalBottomSheetState(
        initialValue = SheetValue.Hidden,
        partiallyExpandedRatio = 0.7f,
        skipPartiallyExpanded = false
    )
    val scope = rememberCoroutineScope()
    var showBottomSheet by remember { mutableStateOf(false) }

    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text(text = "Hello") },
                actions = {
                    IconButton(onClick = {
                        showBottomSheet = true
                        scope.launch {
                            // 直接切换到部分展开状态
                            sheetState.animateTo(SheetValue.PartiallyExpanded)
                        }
                    }) {
                        Icon(imageVector = Icons.Default.MoreVert, contentDescription = "更多选项")
                    }
                }
            )
        }
    ) { innerPadding ->
        Column(modifier = Modifier.padding(innerPadding)) {
            // 主内容区域
        }

        if (showBottomSheet) {
            ModalBottomSheet(
                onDismissRequest = {
                    scope.launch {
                        sheetState.hide()
                    }.invokeOnCompletion {
                        if (!sheetState.isVisible) showBottomSheet = false
                    }
                },
                sheetState = sheetState
            ) {
                // 根据当前状态设置左右内边距
                Column(
                    modifier = Modifier
                        .fillMaxHeight()
                        .padding(
                            horizontal = if (sheetState.currentValue == SheetValue.PartiallyExpanded) 8.dp else 0.dp,
                            vertical = 16.dp
                        )
                ) {
                    Button(onClick = {
                        scope.launch {
                            sheetState.hide()
                        }.invokeOnCompletion {
                            if (!sheetState.isVisible) showBottomSheet = false
                        }
                    }) {
                        Text(text = "隐藏弹窗")
                    }
                    Text(text = "上滑即可全屏展开!")
                }
            }
        }
    }
}

代码说明

  1. 高度控制:通过partiallyExpandedRatio = 0.7f直接定义部分展开的高度占比,无需手动计算屏幕高度,系统自动适配不同设备。
  2. 宽度控制:在内容Column的modifier中,根据sheetState.currentValue动态切换水平内边距,初始状态保留8.dp,全屏时取消内边距。
  3. 状态切换优化:点击按钮后直接调用sheetState.animateTo(SheetValue.PartiallyExpanded),避免默认show操作带来的过渡状态,确保弹窗直接以70%高度显示。
  4. 隐藏逻辑优化:在onDismissRequest和按钮点击事件中,统一先隐藏sheet,再在回调中更新showBottomSheet状态,避免状态不一致问题。

内容的提问来源于stack exchange,提问作者Prakhar_Pathak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 14:48:10