Flutter Auto Route如何结合Bloc可编程式设置初始路由解决跳转失效问题
问题根因
- 你在
BlocListener的回调中修改isLoggedIn变量后没有调用setState,无法触发当前组件的重绘,build方法不会重新执行,因此MaterialApp.router的配置始终使用初始值,不会响应isLoggedIn的变化。 - 你使用的auto_route的
initialRoutes参数仅在路由实例初始化时生效,后续就算组件重绘修改了该参数,也不会触发路由栈的更新,自然不会完成页面跳转。
解决方案
推荐直接在BlocListener中处理路由跳转逻辑,不需要依赖isLoggedIn变量控制初始路由,实现更简单:
import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:harnasik/core/router/app_router.gr.dart'; import 'package:harnasik/core/style/custom_colors.dart'; import 'package:harnasik/features/authorization/presentation/blocs/log_in/log_in_bloc.dart'; import 'package:harnasik/generated/l10n.dart'; import 'package:harnasik/injection_container.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await InjectionContainer().init(); runApp(const HarnasikApp()); } class HarnasikApp extends StatefulWidget { const HarnasikApp({Key? key}) : super(key: key); @override _HarnasikAppState createState() => _HarnasikAppState(); } class _HarnasikAppState extends State<HarnasikApp> { late final LogInBloc logInBloc; final AppRouter _appRouter = sl(); @override void initState() { logInBloc = sl(); super.initState(); logInBloc.add(CheckIfUserLoggedInEvent()); } @override void dispose() { logInBloc.close(); super.dispose(); } @override Widget build(BuildContext context) { return BlocListener<LogInBloc, LogInState>( bloc: logInBloc, listener: (context, state) { if (state is LoggedInState) { // 已登录状态直接替换路由栈为首页,避免返回回到登录页 _appRouter.pushAndPopUntil( const HomeScreen(), predicate: (route) => false, ); } else if (state is LogInErrorState) { print('Error'); // For tests only } }, child: MaterialApp.router( debugShowCheckedModeBanner: false, theme: ThemeData( primaryColor: CustomColors.blue, fontFamily: 'Lato', ), // 初始默认先加载登录页,校验完成后自动跳转 routerDelegate: _appRouter.delegate( initialRoutes: const [LogInScreen()], ), routeInformationParser: _appRouter.defaultRouteParser(), localizationsDelegates: const [ S.delegate, GlobalWidgetsLocalizations.delegate, GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate ], supportedLocales: S.delegate.supportedLocales, ), ); } }
如果你需要避免登录页短暂显示的问题,可以把初始路由改成一个空白加载页,等校验完成后再跳转到对应页面即可。
内容的提问来源于stack exchange,提问作者szakes1
相关产品推荐
相关产品推荐

