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

如何让Bottom Sheet显示在BottomNavBar上方?

系统默认的showModalBottomSheet会以模态方式覆盖整个屏幕(包括BottomNavBar),无法实现你要的效果。你需要通过自定义布局分层来实现,以下是具体实现方案:

核心思路

将BottomNavBar、主内容区域、自定义BottomSheet放在同一个Stack中,让BottomNavBar处于最上层,BottomSheet位于BottomNavBar的上方(屏幕底部到BottomNavBar之间的区域),这样点击logo弹出BottomSheet时,logo始终可见。

代码实现

基础版(带展开/收起动画)

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  bool _isBottomSheetVisible = false;
  // 根据你的BottomNavBar实际高度调整
  final double _bottomNavBarHeight = 60;
  // 设置BottomSheet的最大展开高度
  final double _bottomSheetMaxHeight = 300;

  void _toggleBottomSheet() {
    setState(() {
      _isBottomSheetVisible = !_isBottomSheetVisible;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          // 主内容区域:留出BottomNavBar的高度,避免内容被遮挡
          Positioned.fill(
            bottom: _bottomNavBarHeight,
            child: const Center(child: Text('主页面内容')),
          ),
          // 自定义BottomSheet:位于BottomNavBar上方,带动画展开/收起
          AnimatedPositioned(
            left: 0,
            right: 0,
            bottom: _bottomNavBarHeight,
            height: _isBottomSheetVisible ? _bottomSheetMaxHeight : 0,
            duration: const Duration(milliseconds: 300),
            curve: Curves.easeInOut,
            child: Container(
              decoration: const BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(16),
                  topRight: Radius.circular(16),
                ),
                boxShadow: [BoxShadow(color: Colors.black12, blurRadius: 10)],
              ),
              child: const Center(child: Text('Bottom Sheet内容')),
            ),
          ),
          // BottomNavBar:放在Stack最上层,确保不会被覆盖
          Positioned(
            left: 0,
            right: 0,
            bottom: 0,
            height: _bottomNavBarHeight,
            child: BottomNavigationBar(
              items: [
                BottomNavigationBarItem(
                  icon: GestureDetector(
                    onTap: _toggleBottomSheet,
                    child: Padding(
                      padding: const EdgeInsets.fromLTRB(0, 4, 0, 8),
                      child: Assets.images.logo.svg(),
                    ),
                  ),
                  label: 'Buy',
                ),
                // 其他导航项示例
                const BottomNavigationBarItem(
                  icon: Icon(Icons.search),
                  label: 'Search',
                ),
                const BottomNavigationBarItem(
                  icon: Icons.person,
                  label: 'Profile',
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

进阶版(支持拖拽调整高度)

如果需要像系统BottomSheet一样支持拖拽调整高度,可以用DraggableScrollableSheet替换AnimatedPositioned:

// 替换基础版中的AnimatedPositioned部分
Visibility(
  visible: _isBottomSheetVisible,
  child: Positioned(
    left: 0,
    right: 0,
    bottom: _bottomNavBarHeight,
    height: _bottomSheetMaxHeight,
    child: DraggableScrollableSheet(
      initialChildSize: 1, // 初始展开比例(占满设置的height)
      minChildSize: 0.3, // 最小收起比例
      maxChildSize: 1, // 最大展开比例
      builder: (context, scrollController) {
        return Container(
          decoration: const BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.only(
              topLeft: Radius.circular(16),
              topRight: Radius.circular(16),
            ),
            boxShadow: [BoxShadow(color: Colors.black12, blurRadius: 10)],
          ),
          child: ListView(
            controller: scrollController,
            children: const [
              ListTile(title: Text('选项1')),
              ListTile(title: Text('选项2')),
              ListTile(title: Text('选项3')),
              // 可添加更多列表项
            ],
          ),
        );
      },
    ),
  ),
)

为什么原方法无效?

系统showModalBottomSheet是在根导航器层级弹出的模态组件,层级高于所有页面内容(包括Scaffold的bottomNavigationBar),即使设置useRootNavigator: false也无法改变模态框的层级优先级,因此会遮挡BottomNavBar。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 06:15:06