Flutter中如何通过Go Router导航到Shell Route?
解决方案
你的核心问题在于路由路径冲突(登录页与Shell下的首页共用/),且手动在登录页跳转不符合GoRouter的设计逻辑。用GoRouter自带的redirect功能可以更优雅地实现登录状态的路由切换,具体步骤如下:
1. 修复路由路径冲突
把登录页的路径从/改为/login,避免和Shell下的首页路由匹配冲突:
GoRoute( parentNavigatorKey: _rootNavigator, path: '/login', // 修改为/login name: 'login', builder: (context, state) => AppLoginScreen(key: state.pageKey), ),
2. 用redirect处理认证重定向
在GoRouter初始化时添加redirect回调,通过FirebaseAuth判断登录状态,自动跳转对应路由:
GoRouter router = GoRouter( navigatorKey: _rootNavigator, initialLocation: '/', // 核心:认证状态重定向逻辑 redirect: (context, state) { final user = FirebaseAuth.instance.currentUser; final isLoggedIn = user != null; final isLoginPage = state.location == '/login'; // 未登录且不在登录页 → 跳登录页 if (!isLoggedIn && !isLoginPage) return '/login'; // 已登录且在登录页 → 跳Shell首页 if (isLoggedIn && isLoginPage) return '/'; // 其他情况不做重定向 return null; }, // 其余路由配置保持不变... );
3. 简化登录页代码
移除登录页里的StreamBuilder跳转逻辑,让redirect自动处理路由切换,登录页只负责展示登录UI:
Scaffold( body: Center( child: SizedBox( width: 400, child: ui.SignInScreen( providers: [ui.EmailAuthProvider()], actions: [ ui.AuthStateChangeAction<ui.SignedIn>((context, state) { // 登录成功后触发路由刷新,让redirect生效 GoRouter.of(context).go(HomeScreen.routeName); }), ], ), ), ), );
额外说明
如果需要实时响应登录状态变更(比如用户退出时自动跳回登录页),可以在App根Widget监听authStateChanges(),状态变化时调用GoRouter.of(context).refresh()触发redirect重新执行:
StreamBuilder( stream: FirebaseAuth.instance.authStateChanges(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.active) { GoRouter.of(context).refresh(); } return MaterialApp.router(routerConfig: router); }, )
内容的提问来源于stack exchange,提问作者User
相关产品推荐
相关产品推荐

