Flutter中如何为BottomNavigationBar编写switch case页面路由逻辑?
问题分析
- 你定义的switch跳转逻辑是一个匿名函数,仅在build方法中声明但从未被调用,因此点击底部导航时完全不会触发跳转操作
- 跳转逻辑放置位置错误,build方法会在每次状态更新时重新执行,如果在这里执行跳转,会导致页面反复触发跳转,逻辑完全不符合预期
_onItemTapped点击回调中仅更新了选中下标,没有添加对应的跳转处理,点击底部导航栏只会修改选中状态,不会执行页面跳转- 你当前仅处理了下标0、1的跳转逻辑,剩下的下标2(Watch List)、下标3(Account)没有对应处理,点击这两个选项时不会有任何反应
- 额外提示:如果直接使用
Navigator.pushNamed跳转,每次点击都会往路由栈中叠加新页面,点击返回键会回到上一个页面,不符合底部导航栏常驻切换的常规交互,更推荐在承载该底部导航的父页面中使用IndexedStack或者PageView来切换对应下标显示的页面
修正方案
首先删除build方法开头那段无用的匿名函数代码,再把跳转逻辑移到_onItemTapped方法中即可,修改后的核心代码如下:
void _onItemTapped(int index) { setState(() { _selectedIndex = index; }); // 直接用传入的index判断,不需要等setState异步执行完成 switch (index) { case 0: Navigator.of(context).pushNamed('/homepage'); break; case 1: Navigator.of(context).pushNamed('/cardpage'); break; case 2: // 补充Watch List页面对应的路由即可 Navigator.of(context).pushNamed('/watchpage'); break; case 3: // 补充Account页面对应的路由即可 Navigator.of(context).pushNamed('/accountpage'); break; } }
如果你需要实现底部导航常驻、切换页面不会触发路由跳转的效果,可以按以下方案调整:
- 在承载
BottomNavigationEzyMember的父页面中定义页面列表
final List<Widget> _pages = [ HomePage(), CardPage(), WatchPage(), AccountPage(), ];
- 父页面的build方法中用
IndexedStack承载页面和底部导航:
int _selectedIndex = 0; @override Widget build(BuildContext context) { return Scaffold( body: IndexedStack( index: _selectedIndex, children: _pages, ), bottomNavigationBar: BottomNavigationEzyMember( // 将选中下标和点击回调提到父页面管理 currentIndex: _selectedIndex, onTap: (index) { setState(() { _selectedIndex = index; }); }, ), ); }
内容的提问来源于stack exchange,提问作者Jian Yuan Ng
相关产品推荐
相关产品推荐

