如何在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,提问作者Никита Муравьёв
相关产品推荐
相关产品推荐

