如何使用Jetpack Compose的BottomSheetScaffold实现底部弹窗三态切换?
用BottomSheetScaffold实现三级高度的底部弹窗
完全可以通过BottomSheetScaffold实现你需要的三级高度切换逻辑,核心是利用BottomSheet的自定义锚点特性来定义折叠、半高、全屏三个状态的高度。以下是具体实现方案:
实现步骤
- 定义三个状态的高度:根据需求设置折叠状态的固定高度、屏幕半高、全屏高度。
- 创建带自定义锚点的BottomSheetState:通过
rememberBottomSheetState传入锚点集合,指定初始状态为折叠。 - 配置BottomSheetScaffold:关联自定义的BottomSheetState,设置弹窗内容和主内容区域。
代码示例
import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close import androidx.compose.material3.BottomSheetScaffold import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.rememberBottomSheetScaffoldState import androidx.compose.material3.rememberBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.unit.dp @OptIn(ExperimentalMaterial3Api::class) @Composable fun ThreeLevelBottomSheet() { val screenHeight = LocalConfiguration.current.screenHeightDp.dp // 定义三个状态的高度 val collapsedHeight = 60.dp val halfScreenHeight = screenHeight / 2 val fullScreenHeight = screenHeight // 创建带自定义锚点的BottomSheetState,初始为折叠状态 val bottomSheetState = rememberBottomSheetState( initialValue = androidx.compose.material3.BottomSheetValue.Collapsed, anchors = setOf(collapsedHeight, halfScreenHeight, fullScreenHeight) ) val scaffoldState = rememberBottomSheetScaffoldState(bottomSheetState = bottomSheetState) BottomSheetScaffold( scaffoldState = scaffoldState, sheetPeekHeight = collapsedHeight, sheetContent = { Box( modifier = Modifier .fillMaxWidth() .heightIn(min = collapsedHeight, max = fullScreenHeight) .background(MaterialTheme.colorScheme.surfaceVariant) ) { // 弹窗内容示例 Text( text = when (bottomSheetState.currentValue) { androidx.compose.material3.BottomSheetValue.Collapsed -> "折叠状态" else -> if (bottomSheetState.currentAnchor == halfScreenHeight) "半高状态" else "全屏状态" }, modifier = Modifier.align(Alignment.Center) ) // 关闭按钮示例 IconButton( onClick = { /* 关闭逻辑 */ }, modifier = Modifier.align(Alignment.TopEnd) ) { Icon(Icons.Default.Close, contentDescription = "关闭弹窗") } } } ) { innerPadding -> // 主内容区域 Box( modifier = Modifier .padding(innerPadding) .fillMaxSize() .background(MaterialTheme.colorScheme.background), contentAlignment = Alignment.Center ) { Text(text = "主内容区域") } } }
关键说明
- 锚点机制:通过
anchors参数传入三个高度值,BottomSheet会自动在滑动时停靠在这些锚点上,实现“折叠→半高→全屏”以及反向的滑动逻辑。 - 版本要求:确保使用的Compose Material 3版本在1.1.0及以上(或Material 2 1.6.0及以上),自定义锚点特性是较新的功能。
- 高度自定义:你可以根据实际需求调整
collapsedHeight的数值,半高也可以结合WindowInsets减去状态栏、导航栏高度,让布局更贴合实际场景。
内容的提问来源于stack exchange,提问作者Heleena Joy
相关产品推荐
相关产品推荐

