Flutter easy_localization无法正确设置iOS应用指定语言问题
问题描述
我开发的Flutter应用支持瑞典语(sv)和英语(en),这两种语言可在iOS应用设置中选择,但存在以下问题:
- 若用户系统主语言非瑞典语或英语,应用启动时无法获取到选定的瑞典语,仅能读取系统主语言,最终默认切换为英语;
- 若用户系统主语言为瑞典语或英语,且将应用语言设置为瑞典语,虽能正确读取到应用语言(如sv_SE),但easy_localization仍无法将其设置为当前语言,MyApp中
context.locale仍为英语(en)。
现有代码
main函数
Future<void> main() async { runZonedGuarded<Future<void>>(() async { WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized(); await EasyLocalization.ensureInitialized(); Locale currentLocaleForApp = WidgetsBinding.instance.platformDispatcher.locale; // <- This only gets set to "sv" if the OS main locale is either Swedish or English, otherwise it becomes the main OS locale and will default to "en" regardless what they selected for the app. runApp(ProviderScope( child: EasyLocalization( key: UniqueKey(), supportedLocales: [const Locale('sv'), const Locale('en')], path: 'assets/translations', fallbackLocale: Locale('en'), useOnlyLangCode: true, child: MyApp()))); }, (error, stack) => FirebaseCrashlytics.instance.recordError(error, stack)); }
MaterialApp部分
return GestureDetector( onTap: () => FocusManager.instance.primaryFocus?.unfocus(), child: ResponsiveSizer( builder: (context, orientation, screenType) { return MaterialApp( locale: context.locale, // <- This never changes to "sv" unless main OS is Swedish localizationsDelegates: context.localizationDelegates, supportedLocales: context.supportedLocales, onGenerateTitle: (context) { return "My app name"; }, theme: ThemeData( splashColor: Colors.transparent, visualDensity: VisualDensity.adaptivePlatformDensity, primarySwatch: BirdsTheme.CompanyColors.primary, fontFamily: 'Poppins'), navigatorKey: _navigationService.navigatorKey, onGenerateRoute: generateRoute, home: child); }, ));
解决方案
1. 修正Locale读取逻辑,获取iOS应用级语言设置
WidgetsBinding.instance.platformDispatcher.locale只能读取系统主语言,无法获取iOS单独设置的应用语言。要获取应用的首选语言列表,需使用WidgetsBinding.instance.platformDispatcher.locales,该列表会按用户在应用设置中选择的语言优先级排序。
修改main函数中的Locale获取逻辑:
// 从应用首选语言列表中筛选出支持的语言 Locale? appPreferredLocale; final supportedLocaleCodes = {'sv', 'en'}; for (final locale in WidgetsBinding.instance.platformDispatcher.locales) { if (supportedLocaleCodes.contains(locale.languageCode)) { appPreferredLocale = Locale(locale.languageCode); break; } } // 优先使用应用首选语言,无匹配则 fallback 到英语 final initialLocale = appPreferredLocale ?? const Locale('en');
将得到的initialLocale传入EasyLocalization的startLocale参数:
EasyLocalization( key: UniqueKey(), supportedLocales: [const Locale('sv'), const Locale('en')], path: 'assets/translations', fallbackLocale: const Locale('en'), useOnlyLangCode: true, startLocale: initialLocale, // 添加初始语言参数 child: MyApp())
2. 开启语言设置持久化
添加saveLocale: true参数,让easy_localization记住用户的语言选择,避免重启后重置:
EasyLocalization( key: UniqueKey(), supportedLocales: [const Locale('sv'), const Locale('en')], path: 'assets/translations', fallbackLocale: const Locale('en'), useOnlyLangCode: true, startLocale: initialLocale, saveLocale: true, // 持久化用户语言设置 child: MyApp())
3. 验证MaterialApp配置
你当前MaterialApp中使用context.locale的配置是正确的,只需确保该context处于EasyLocalization的子树中即可,现有代码结构已满足此要求,无需修改。
内容的提问来源于stack exchange,提问作者Majoren
相关产品推荐
相关产品推荐

