Flutter中bottomnavigationbar场景下点击PageB按钮返回rootViewController如何实现
实现方案
你的现有架构已经为每个Tab配置了独立的Navigator维护专属路由栈,和iOS多Tab下每个Tab独立维护导航栈的逻辑完全匹配,只需要调用对应Tab的Navigator的popUntil方法即可实现回到当前Tab根页面的效果,具体修改步骤如下:
步骤1:暴露App状态的控制方法
首先修改main.dart中的AppState类,将Tab切换方法改为公开,同时提供跨组件获取AppState实例的方法:
class AppState extends State<App> { static int currentTab = 0; final List<TabItem> tabs = [ TabItem( tabName: "Page A", icon: Icons.home_outlined, page: PageA(), ), TabItem( tabName: "Page B", icon: Icons.search, page: PageB(), ), ]; // 新增:提供跨组件获取AppState实例的方法 static AppState of(BuildContext context) { return context.findAncestorStateOfType<AppState>()!; } AppState() { tabs.asMap().forEach((index, details) { details.setIndex(index); }); } // 修改:去掉下划线改为公开方法 void selectTab(int index) { if (index == currentTab) { tabs[index].key.currentState!.popUntil((route) => route.isFirst); } else { setState(() => currentTab = index); } } // 其余代码保持不变,bottomNavigationBar的onSelectTab参数改为selectTab即可 @override Widget build(BuildContext context) { return WillPopScope( // ...原有逻辑不变 child: Scaffold( // ...原有逻辑不变 bottomNavigationBar: BottomNavigation( onSelectTab: selectTab, // 这里改成公开的selectTab tabs: tabs, ), ), ); } }
步骤2:在Page B的按钮中调用返回根页面逻辑
在Page B中心按钮的点击回调中,调用上述公开的selectTab方法即可,因为当前处于Page B(对应Tab索引为1),传入索引1就会触发当前Tab的导航栈弹到根路由:
class PageB extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: Center( child: ElevatedButton( onPressed: () { // 传入Page B对应的Tab索引1,触发回到当前Tab根页面逻辑 AppState.of(context).selectTab(1); }, child: Text('回到根页面'), ), ), ); } }
实现原理
你代码中每个TabItem都绑定了独立的GlobalKey<NavigatorState>,popUntil((route) => route.isFirst)会清空当前Tab导航栈中除初始根路由外的所有路由,和iOS原生popToRootViewController的效果完全一致,且不会影响其他Tab的导航栈状态。
内容的提问来源于stack exchange,提问作者Mohammed Nabil
相关产品推荐
相关产品推荐

