展开时BottomSheetScaffold无法贴合BottomNavigation顶部的问题排查
问题描述
在带有BottomNavigation的页面中使用BottomSheetScaffold时,展开BottomSheet后,其底部会向上偏移一小段距离;但移除BottomNavigation后,一切功能正常。
代码示例
@Composable fun ContainerView() { val scaffoldState = rememberBottomSheetScaffoldState() val appBarHeight = getAppBarHeight( scaffoldState.bottomSheetState.offset.value, scaffoldState.bottomSheetState.targetValue ) Box(modifier = Modifier.fillMaxSize()) { BottomSheetScaffold( sheetContent = { BottomSheetContent( appBarHeight = appBarHeight ) }, scaffoldState = scaffoldState, sheetPeekHeight = 100.dp, sheetBackgroundColor = greysWhite, sheetShape = Shapes.extraLarge .copy(bottomEnd = CornerSize(0), bottomStart = CornerSize(0)) ) { Text("Hello World") } Surface(elevation = 14.dp) { AppBar( modifier = Modifier, appBarHeight = appBarHeight ) { } } } } @Composable fun BottomSheetContent( appBarHeight: Dp, ) { val padding by animateDpAsState( targetValue = appBarHeight, animationSpec = tween(durationMillis = animationDuration) ) val scrollState = rememberScrollState() Column( modifier = Modifier .fillMaxWidth() .padding(top = padding) .verticalScroll(scrollState) .padding(horizontal = 16.dp) ) { repeat((0..22).count()) { Text("$it", modifier = Modifier.padding(16.dp)) } } }
问题截图

成因分析
- BottomSheetScaffold的内边距计算未覆盖自定义BottomNavigation:BottomSheetScaffold默认只会适配系统导航栏的内边距,对于页面中自定义的BottomNavigation,它无法自动感知其存在,导致BottomSheet的底部预留空间错误,展开时出现向上偏移。
- 布局层级冲突:如果BottomNavigation和BottomSheetScaffold处于同级布局(比如都在同一个Box容器内),Scaffold不会将BottomNavigation的高度纳入自身布局计算逻辑,进而导致BottomSheet的底部位置偏移。
修复方案
方案1:手动补偿BottomNavigation高度
在BottomSheetContent的底部添加与BottomNavigation高度一致的padding,直接修正偏移问题:
@Composable fun BottomSheetContent( appBarHeight: Dp, bottomNavHeight: Dp = 56.dp // Material3默认BottomNavigation高度 ) { val padding by animateDpAsState( targetValue = appBarHeight, animationSpec = tween(durationMillis = animationDuration) ) val scrollState = rememberScrollState() Column( modifier = Modifier .fillMaxWidth() .padding(top = padding) .verticalScroll(scrollState) .padding(horizontal = 16.dp) .padding(bottom = bottomNavHeight) // 加入BottomNavigation高度的底部padding ) { repeat((0..22).count()) { Text("$it", modifier = Modifier.padding(16.dp)) } } }
方案2:将BottomNavigation纳入BottomSheetScaffold的content区域
把BottomNavigation放在BottomSheetScaffold的content参数内,利用Scaffold提供的innerPadding自动处理布局间距,让Scaffold自动调整BottomSheet的底部位置:
@Composable fun ContainerView() { val scaffoldState = rememberBottomSheetScaffoldState() val bottomNavHeight = 56.dp val appBarHeight = getAppBarHeight( scaffoldState.bottomSheetState.offset.value, scaffoldState.bottomSheetState.targetValue ) Box(modifier = Modifier.fillMaxSize()) { BottomSheetScaffold( sheetContent = { BottomSheetContent( appBarHeight = appBarHeight ) }, scaffoldState = scaffoldState, sheetPeekHeight = 100.dp, sheetBackgroundColor = greysWhite, sheetShape = Shapes.extraLarge .copy(bottomEnd = CornerSize(0), bottomStart = CornerSize(0)) ) { innerPadding -> Column(modifier = Modifier.padding(innerPadding).fillMaxSize()) { Text("Hello World") // 用Spacer将BottomNavigation固定在底部 Spacer(modifier = Modifier.weight(1f)) BottomNavigation(modifier = Modifier.fillMaxWidth()) { // 填充BottomNavigation的菜单项 } } } Surface(elevation = 14.dp) { AppBar( modifier = Modifier, appBarHeight = appBarHeight ) { } } } }
方案3:手动设置BottomSheetScaffold的contentPadding
如果BottomNavigation必须放在Scaffold外部,可以通过contentPadding参数手动指定底部内边距,让Scaffold感知到BottomNavigation的存在:
BottomSheetScaffold( sheetContent = { /* 原有内容 */ }, scaffoldState = scaffoldState, sheetPeekHeight = 100.dp, contentPadding = PaddingValues(bottom = 56.dp), // 设置与BottomNavigation等高的底部内边距 // 其他参数不变 ) { // 原有content内容 }
内容的提问来源于stack exchange,提问作者Ibrahim Abousalem
相关产品推荐
相关产品推荐

