Flutter切换应用主题时路由重置问题求助
问题解决:切换主题时保留设置页面路由
问题根源
每次切换主题触发themeMode变化时,MesMaterialApp的build方法会重新执行,而你在build里每次都调用MesAppRouter.getRouter()创建新的GoRouter实例。新的GoRouter会使用initialLocation初始化路由栈,导致当前设置页面被替换,自动回到首页。
解决方案
核心思路是让GoRouter实例保持单例,避免每次主题变更都重建路由栈。通过Riverpod的Provider缓存GoRouter,只在应用启动时初始化一次初始路由位置。
步骤1:用Riverpod Provider管理GoRouter单例
创建一个Provider来提供GoRouter,确保只在应用启动时创建一次:
final goRouterProvider = Provider<GoRouter>((ref) { // 仅在Provider初始化时获取一次isOnboarded,后续变更不影响初始路由 final isOnboarded = ref.watch(settingsProvider.select((s) => s.isOnboarded)); return MesAppRouter.getRouter( initialLocation: isOnboarded ? HomeRoute.path : WelcomeRoute.path, ); });
步骤2:修改MesMaterialApp获取Router的方式
在MesMaterialApp的build方法中,从Provider获取缓存的Router,而非每次重建:
class MesMaterialApp extends ConsumerWidget { MesMaterialApp({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { // 从Provider获取单例Router,不会随主题变更重建 final router = ref.watch(goRouterProvider); final brightness = View.of(context).platformDispatcher.platformBrightness; TextTheme textTheme = createTextTheme(context, "Poppins", "Lato"); AppBarTheme appBarTheme = createAppBarTheme(brightness == Brightness.light); MaterialTheme theme = MaterialTheme(textTheme, appBarTheme); return MaterialApp.router( debugShowCheckedModeBanner: false, title: 'Flutter Demo', theme: theme.light(), darkTheme: theme.dark(), themeMode: ref.watch(settingsProvider.select((s) => s.theme)), highContrastTheme: theme.lightHighContrast(), highContrastDarkTheme: theme.darkHighContrast(), localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, routerConfig: router, ); } }
补充:处理isOnboarded后续变更
如果需要在用户完成引导后从Welcome页跳转到首页,不要重建Router,而是在settingsProvider中监听isOnboarded变化,主动导航:
// 在settingsProvider的逻辑中添加监听 ref.listen(settingsProvider.select((s) => s.isOnboarded), (previous, next) { if (next == true && previous == false) { final router = ref.read(goRouterProvider); router.go(HomeRoute.path); } });
这样修改后,切换主题时只会更新themeMode,路由栈保持不变,用户可以停留在设置页面实时看到主题变化效果,和原生Android的行为一致。
内容的提问来源于stack exchange,提问作者Mervin Hemaraju
相关产品推荐
相关产品推荐

