Flutter如何实现bottomNavigationBar在应用所有页面显示
你当前的实现是将底部导航栏绑定在主路由的Scaffold上,使用默认Navigator跳转子页面时,新页面会覆盖整个当前路由栈的Scaffold,因此导航栏会被隐藏。要实现全页面展示底部导航,推荐以下两种可直接落地的方案:
方案1:嵌套Navigator(兼容性最优,推荐使用)
核心逻辑是给每个底部导航Tab分配独立的内部路由栈,子页面跳转仅在对应Tab的路由栈内完成,不会跳出外层带底部导航的Scaffold,保留原生路由的所有特性(传参、动画、返回键逻辑等)。
核心改造代码:
// 1. 预先为4个Tab定义独立的NavigatorKey final List<GlobalKey<NavigatorState>> _tabNavigatorKeys = [ GlobalKey<NavigatorState>(), GlobalKey<NavigatorState>(), GlobalKey<NavigatorState>(), GlobalKey<NavigatorState>(), ]; // 2. 改造原有buildPages方法,用IndexedStack+独立Navigator包裹每个Tab的首页 Widget buildPages(int index) { return WillPopScope( // 适配安卓物理返回键:优先退回当前Tab内部的子页面,内部栈为空时再退出应用 onWillPop: () async { final currentTabNavigator = _tabNavigatorKeys[_index].currentState; if (currentTabNavigator!.canPop()) { currentTabNavigator.pop(); return false; } return true; }, child: IndexedStack( index: _index, // 保留切换Tab时的页面状态,不会每次切换都重建 children: [ _buildSingleTabNavigator(0, pageStart()), _buildSingleTabNavigator(1, _pages[1]), _buildSingleTabNavigator(2, _pages[2]), _buildSingleTabNavigator(3, _pages[3]), ], ), ); } // 封装单个Tab的独立导航器 Widget _buildSingleTabNavigator(int tabIndex, Widget tabRootPage) { return Navigator( key: _tabNavigatorKeys[tabIndex], onGenerateRoute: (routeSettings) { return MaterialPageRoute( builder: (context) => tabRootPage, settings: routeSettings, ); }, ); }
子页面跳转规范:
后续所有子页面跳转不要指定rootNavigator: true,直接使用当前上下文的Navigator即可,跳转后底部导航会保留:
// 正确跳转写法 Navigator.of(context).push(MaterialPageRoute(builder: (context) => 自定义子页面()));
方案2:PageView全页面托管
如果你的应用所有页面都不需要隐藏底部导航,且路由逻辑简单,可以把所有页面都放到PageView的子节点列表中,点击底部导航或内部跳转时,仅通过PageController切换对应页面索引即可。这种方案实现最简单,但不支持原生路由的栈管理、参数传递等特性,适合轻量化应用。
特殊场景适配:
如果有个别页面需要临时隐藏底部导航,可以在外层State中定义一个bool _showBottomNav = true变量,控制Scaffold的bottomNavigationBar属性,需要隐藏时调用setState(() => _showBottomNav = false)即可。
内容的提问来源于stack exchange,提问作者Kaya Ryuuna
相关产品推荐
相关产品推荐

