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

展开时BottomSheetScaffold无法贴合BottomNavigation顶部的问题排查

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))
        }
    }
}

问题截图

正常状态(无BottomNavigation) 偏移状态(有BottomNavigation)

成因分析

  1. BottomSheetScaffold的内边距计算未覆盖自定义BottomNavigation:BottomSheetScaffold默认只会适配系统导航栏的内边距,对于页面中自定义的BottomNavigation,它无法自动感知其存在,导致BottomSheet的底部预留空间错误,展开时出现向上偏移。
  2. 布局层级冲突:如果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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 05:05:24