Modal Bottom Sheet高度设置求助:如何自定义弹窗高度?
解决Modal Bottom Sheet高度适配问题
要实现大屏完整显示、小屏占80%屏幕且不侵入状态栏的效果,你需要结合系统窗口Insets和屏幕高度判断来设置最大高度,而非用屏幕宽度判断。以下是具体实现方案:
核心思路
- 获取屏幕可用显示高度:扣除状态栏、导航栏等系统UI占用的空间,避免内容侵入系统状态栏。
- 动态判断设备尺寸:设定一个大屏高度阈值(比如600dp),低于该阈值的小屏设备将Bottom Sheet高度限制为可用高度的80%;大屏设备则让内容自然展开,不限制最大高度。
修改后的代码实现
@OptIn(ExperimentalMaterial3Api::class) @Composable internal fun TripListModalWithDetails( state: TripListViewState, uiIntent: (TripListUiIntent) -> Unit ) { val sheetState = rememberModalBottomSheetState( skipPartiallyExpanded = true ) // 获取系统窗口Insets(状态栏、导航栏等系统UI的间距) val windowInsets = WindowInsets.systemBars.asPaddingValues() // 获取屏幕配置信息 val configuration = LocalConfiguration.current // 屏幕总高度(单位:dp) val screenHeightDp = configuration.screenHeightDp.dp // 计算可用显示高度:总高度减去状态栏和导航栏的高度 val availableHeight = screenHeightDp - windowInsets.calculateTopPadding() - windowInsets.calculateBottomPadding() // 自定义大屏阈值,可根据需求调整 val largeScreenThreshold = 600.dp // 计算Bottom Sheet的最大允许高度 val maxSheetHeight = if (screenHeightDp < largeScreenThreshold) { availableHeight * 0.8f } else { // 大屏不限制高度,让内容自然展开 Float.POSITIVE_INFINITY.dp } if (state.detailsId != null) { ModalBottomSheet( onDismissRequest = { uiIntent(TripListUiIntent.HideTripDetails) }, sheetState = sheetState, tonalElevation = TONAL_ELEVATION, dragHandle = {} ) { Column( modifier = Modifier .background(MaterialTheme.colorScheme.background) .padding(vertical = MaterialTheme.whereNowSpacing.space24) .padding(horizontal = MaterialTheme.whereNowSpacing.space16) // 应用计算好的最大高度 .maxHeight(maxSheetHeight) .verticalScroll(rememberScrollState()) ) { Text( modifier = Modifier.align(Alignment.CenterHorizontally), text = stringResource(R.string.trip_modal_departure), style = MaterialTheme.typography.titleLarge.copy(MaterialTheme.colorScheme.primary) ) HorizontalDivider( modifier = Modifier.padding( vertical = MaterialTheme.whereNowSpacing.space16, horizontal = MaterialTheme.whereNowSpacing.space8 ) ) // 剩余内容... } } } }
关键说明
- WindowInsets的作用:通过
WindowInsets.systemBars获取系统UI的间距,确保Bottom Sheet内容不会被状态栏、导航栏遮挡,也不会侵入这些系统区域。 - 用高度判断设备尺寸:垂直方向的显示空间是你要适配的核心,用屏幕高度作为判断依据比宽度更合理。
- 动态maxHeight:小屏时限制为可用高度的80%,保证内容有足够显示空间同时不占满屏幕;大屏时不限制高度,让内容完整展示。
内容的提问来源于stack exchange,提问作者joj
相关产品推荐
相关产品推荐

