使用MaterialApp.router()时如何在Flutter中程序化修改Locale
解决Flutter中Locale变更无法全局生效的问题
你遇到的核心问题是:直接给MaterialApp.router的locale传值,无法在Locale变化时触发本地化资源的重新加载,而Localizations.override需要依赖已存在的本地化上下文,不能放在MaterialApp外层。
最优解决方案:利用MaterialApp.router的builder参数全局覆盖Locale
通过builder参数可以获取到MaterialApp内部的BuildContext(已包含本地化上下文),在这里使用Localizations.override就能全局生效,无需在每个页面单独处理。
修改后的代码如下:
final themeMode = context.select<PreferencesChangeNotifier, ThemeMode>((notifier) => notifier.themeMode); final locale = context.select<LocaleChangeNotifier, Locale>((notifier) => notifier.locale); return MaterialApp.router( debugShowCheckedModeBanner: false, scaffoldMessengerKey: MyApp.rootScaffoldMessengerKey, localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, routeInformationParser: _routeInformationParser, routerDelegate: _routerDelegate, title: 'MyApp', theme: AppTheme.instance.lightTheme, darkTheme: AppTheme.instance.darkTheme, themeMode: themeMode, // 新增builder参数,全局覆盖Locale builder: (context, child) { return Localizations.override( context: context, locale: locale, child: child!, ); }, );
原理说明
builder的context是MaterialApp初始化后的上下文,已经包含了本地化相关的配置(localizationsDelegates、supportedLocales等),所以可以安全使用Localizations.override。- 当
locale通过context.select更新时,MaterialApp会重建,builder里的Localizations.override会强制触发本地化资源的重新加载,确保所有子Widget都使用新的Locale。 - 这种方式只会加载当前Locale对应的资源,不会出现重复加载的问题。
内容的提问来源于stack exchange,提问作者Lukas Nevosad
相关产品推荐
相关产品推荐

