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

Jetpack Compose中实现带底部固定按钮的ModalBottomSheet

解决方案

1. 自定义部分展开比例

Material3 的 ModalBottomSheet 无需修改底层源码,直接通过 rememberModalBottomSheetState 的 halfExpandedRatio 参数就能设置自定义部分展开比例。该参数接受0-1之间的浮点数,代表Sheet高度占屏幕总高度的比例。

比如要设置为屏幕高度的70%,代码如下:

val sheetState = rememberModalBottomSheetState(
    initialValue = ModalBottomSheetValue.HalfExpanded,
    halfExpandedRatio = 0.7f // 替换默认的0.5f,自定义比例
)

2. 实现底部固定按钮布局

要让按钮固定在Sheet底部、中间列表可滚动,用Column包裹内容,给LazyColumn添加Modifier.weight(1f),让它填充头部与按钮之间的剩余空间:

ModalBottomSheet(
    sheetState = sheetState,
    onDismissRequest = { /* 关闭逻辑 */ },
    dragHandle = { BottomSheetDragHandle() }
) {
    Column(Modifier.fillMaxWidth()) {
        // 顶部头部组件
        Text(
            text = "头部标题",
            modifier = Modifier.fillMaxWidth().padding(16.dp),
            style = MaterialTheme.typography.headlineSmall
        )

        // 中间可滚动列表
        LazyColumn(Modifier.weight(1f).padding(horizontal = 16.dp)) {
            items(50) { index ->
                Text(text = "列表项 $index", modifier = Modifier.padding(vertical = 8.dp))
            }
        }

        // 底部固定按钮
        Button(
            onClick = { /* 按钮逻辑 */ },
            modifier = Modifier.fillMaxWidth().padding(16.dp)
        ) {
            Text("确认操作")
        }
    }
}

3. 完整可运行示例

把两者结合,完整代码如下:

@Composable
fun CustomFixedButtonBottomSheet() {
    val sheetState = rememberModalBottomSheetState(
        initialValue = ModalBottomSheetValue.HalfExpanded,
        halfExpandedRatio = 0.7f
    )
    val scope = rememberCoroutineScope()

    Scaffold { paddingValues ->
        Button(
            onClick = { scope.launch { sheetState.show() } },
            modifier = Modifier.padding(paddingValues)
        ) {
            Text("打开底部Sheet")
        }

        ModalBottomSheet(
            sheetState = sheetState,
            onDismissRequest = { scope.launch { sheetState.hide() } },
            dragHandle = { BottomSheetDragHandle() }
        ) {
            Column(Modifier.fillMaxWidth()) {
                // 头部区域
                Text(
                    "自定义底部Sheet",
                    modifier = Modifier.fillMaxWidth().padding(16.dp),
                    style = MaterialTheme.typography.titleLarge
                )

                // 滚动列表区域
                LazyColumn(Modifier.weight(1f)) {
                    items(30) { index ->
                        Text(
                            "列表条目 $index",
                            modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 8.dp)
                        )
                    }
                }

                // 固定底部按钮
                Button(
                    onClick = { scope.launch { sheetState.hide() } },
                    modifier = Modifier.fillMaxWidth().padding(16.dp)
                ) {
                    Text("完成")
                }
            }
        }
    }
}

这套方案既实现了自定义的部分展开比例,又保证底部按钮固定、中间列表正常滚动,完全匹配你想要的效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 22:47:46