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

如何在ModalBottomSheet中实现固定位置的按钮?

解决ModalBottomSheet中按钮固定底部的问题

要实现按钮在ModalBottomSheet的半屏/全屏状态下始终固定在底部,核心是把内容区域和按钮区域分离,用Column布局分配空间,让内容区域可滚动,按钮区域固定在底部。具体实现如下:

修改后的完整代码

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun BottomSheetExample() {
    val coroutineScope = rememberCoroutineScope()
    val sheetState = rememberModalBottomSheetState(
        initialValue = ModalBottomSheetValue.Hidden
    )
    val openSheet = remember { mutableStateOf(false) }

    Scaffold { paddingValues ->
        Box(
            modifier = Modifier
                .fillMaxSize()
                .padding(paddingValues),
            contentAlignment = Alignment.Center
        ) {
            Button(onClick = { openSheet.value = true }) {
                Text(text = "打开底部弹窗")
            }

            if (openSheet.value) {
                ModalBottomSheet(
                    onDismissRequest = { openSheet.value = false },
                    shape = SquircleShape(32.dp, 32.dp, 0.dp, 0.dp, cornerSmoothing = CornerSmoothing.Medium),
                    containerColor = Color.White,
                    content = {
                        // 用Column作为根容器,分离内容区和按钮区
                        Column(
                            modifier = Modifier
                                .fillMaxSize()
                                .padding(16.dp)
                        ) {
                            // 内容区域:占满剩余空间,支持滚动
                            Box(
                                modifier = Modifier
                                    .weight(1f)
                                    .verticalScroll(rememberScrollState())
                                    .background(Color.LightGray)
                                    .padding(16.dp)
                            ) {
                                // 这里放长内容,测试滚动效果
                                Column {
                                    repeat(20) {
                                        Text(text = "这是底部弹窗的内容行 $it", modifier = Modifier.padding(vertical = 8.dp))
                                    }
                                }
                            }

                            // 固定底部的按钮
                            Button(
                                modifier = Modifier.fillMaxWidth(),
                                onClick = { openSheet.value = false }
                            ) {
                                Text(text = "确认")
                            }
                        }
                    }
                )
            }
        }
    }
}

@Composable
fun rememberModalBottomSheetState(
    initialValue: ModalBottomSheetValue
) = remember {
    ModalBottomSheetState(initialValue = initialValue)
}

data class ModalBottomSheetState(
    val initialValue: ModalBottomSheetValue
)

enum class ModalBottomSheetValue {
    Hidden, Expanded
}

关键实现要点

  • 用Column拆分区域:把ModalBottomSheet的内容根容器换成Column,让内容区和按钮区垂直排列。
  • 内容区设置weight(1f):给内容区域添加Modifier.weight(1f),让它占据BottomSheet中除按钮外的所有可用空间,确保按钮始终在底部。
  • 内容区添加滚动:给内容区域加上verticalScroll(rememberScrollState()),当内容超过BottomSheet高度时可以滚动,按钮不会跟着滚动。
  • 按钮直接放在Column末尾:按钮不需要添加滚动或weight属性,自然固定在Column的底部,也就是BottomSheet的底部。

为什么之前的方案失效

之前把按钮放在嵌套的Box里,按钮和内容属于同一个滚动容器,当内容滚动时按钮会跟着移动。现在通过Column+weight的方式把滚动区域和固定区域完全分离,就解决了这个问题。

内容的提问来源于stack exchange,提问作者Никита Муравьёв

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 01:10:18