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

Flutter应用中BottomNavigationBar跳转消失问题的解决方法

解决Flutter跳转后BottomNavigationBar消失的问题

你遇到的问题根源很直接:用pushReplacement跳转时,直接把包含底部导航栏的父页面替换成了WorkoutsPage,新页面本身没嵌套底部导航,自然就看不到了。下面给你两种实用的解决思路:

思路一:直接切换底部导航的选中索引(推荐)

既然你的底部导航本来就是通过_selectedIndex切换页面,那提交按钮触发时,直接修改这个索引就行,根本不需要用Navigator跳转。

实现步骤:

  1. 给底部导航所在的页面(比如叫MainPage)定义一个GlobalKey,用来跨页面调用状态方法:
// 在MainPage外部定义全局key
final GlobalKey<MainPageState> mainPageKey = GlobalKey<MainPageState>();

class MainPage extends StatefulWidget {
  const MainPage({super.key}) : super(key: mainPageKey);

  @override
  MainPageState createState() => MainPageState();
}
  1. 在MainPage的State里,添加修改索引的方法:
class MainPageState extends State<MainPage> {
  int _selectedIndex = 0;
  // 页面列表,对应底部导航的选项
  final List<Widget> _pages = const [HomeScreen(), WorkoutsPage()];

  // 暴露修改索引的方法
  void switchToPage(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _pages[_selectedIndex],
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _selectedIndex,
        onTap: switchToPage,
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'),
          BottomNavigationBarItem(icon: Icon(Icons.fitness_center), label: '训练'),
        ],
      ),
    );
  }
}
  1. 提交按钮的点击事件里,直接调用这个方法切换到WorkoutsPage:
// 假设1是WorkoutsPage在_pages里的索引
mainPageKey.currentState?.switchToPage(1);

这样操作后,底部导航栏会一直保留,因为你只是在父页面的body里切换子页面,没有替换整个路由。

思路二:调整路由结构,让底部导航作为父路由

如果一定要用Navigator跳转,那得让底部导航所在的页面始终作为根路由,WorkoutsPage作为它的子页面存在。可以给每个底部导航选项配一个独立的子导航器:

class MainPageState extends State<MainPage> {
  int _selectedIndex = 0;
  // 给每个页面配一个导航器key
  final List<GlobalKey<NavigatorState>> _navigatorKeys = [
    GlobalKey<NavigatorState>(),
    GlobalKey<NavigatorState>(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: IndexedStack(
        index: _selectedIndex,
        children: [
          // 首页的子导航器
          Navigator(
            key: _navigatorKeys[0],
            onGenerateRoute: (settings) => MaterialPageRoute(
              builder: (context) => const HomeScreen(),
            ),
          ),
          // 训练页的子导航器
          Navigator(
            key: _navigatorKeys[1],
            onGenerateRoute: (settings) => MaterialPageRoute(
              builder: (context) => const WorkoutsPage(),
            ),
          ),
        ],
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _selectedIndex,
        onTap: (index) => setState(() => _selectedIndex = index),
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'),
          BottomNavigationBarItem(icon: Icon(Icons.fitness_center), label: '训练'),
        ],
      ),
    );
  }
}

之后提交按钮跳转时,用训练页对应的子导航器:

_navigatorKeys[1].currentState?.pushReplacement(MaterialPageRoute(
  builder: (context) => const WorkoutsPage(),
));

这种方式下,底部导航栏始终在根Scaffold里,不会被替换掉。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 07:15:25