Flutter Easy Localization远程翻译资源运行时切换语言问题求助
解决方案:实现EasyLocalization语言实时切换
以下是针对你的问题的具体修改步骤,解决切换语言后需重启应用的问题:
1. 修复自定义Http加载器的参数不一致问题
你的CustomHttpAssetLoader中默认请求的参数名和成功请求不一致,会导致默认翻译加载失败,先修正这个问题:
class CustomHttpAssetLoader extends AssetLoader { @override Future<Map<String, dynamic>?> load(String path, Locale locale) async { String url = '$path?filename=${locale.languageCode}.json&language=${locale.languageCode}'; final response = await http.get(Uri.parse(url)); if (response.statusCode == 200) { return jsonDecode(response.body); } else { // 统一参数名,和上方请求保持一致 final response = await http.get(Uri.parse('$path?filename=en.json&language=en')); if (response.statusCode == 200) { return jsonDecode(response.body); } else { throw Exception('Failed to load translation file'); } } } }
2. 让MyApp监听语言变化并自动重建
修改MyApp的状态类,监听EasyLocalization的语言流,当语言变化时触发UI重建:
class _MyAppState extends State<MyApp> { late Locale currentLocale; @override void initState() { super.initState(); currentLocale = context.locale; // 监听语言变化,触发App重建 EasyLocalization.of(context)?.localeStream.listen((locale) { if (currentLocale != locale) { setState(() { currentLocale = locale; }); } }); } @override Widget build(BuildContext context) { final Brightness brightness = MediaQuery.of(context).platformBrightness; final bool isDarkMode = brightness == Brightness.dark; return GetMaterialApp( debugShowCheckedModeBanner: false, localizationsDelegates: context.localizationDelegates, supportedLocales: context.supportedLocales, locale: currentLocale, theme: isDarkMode ? ThemeData.dark() : ThemeData.light(), home: Material( child: InkWell( onTap: () { HapticFeedback.heavyImpact(); }, child: SplashScreen(), ), ), ); } }
3. 修改语言切换方法,确保翻译加载完成
更新changeLanguage方法,等待语言设置完成,并在关闭页面时通知上层页面更新:
void changeLanguage(BuildContext context, String newValue) async { Locale newLocale; switch (newValue) { case 'English': newLocale = Locale('en'); break; case 'Hindi': newLocale = Locale('hi'); break; case 'Arabic': newLocale = Locale('ar'); break; case 'French': newLocale = Locale('fr'); break; case 'Spanish': newLocale = Locale('es'); break; case 'German': newLocale = Locale('de'); break; case 'Italian': newLocale = Locale('it'); break; case 'Russian': newLocale = Locale('ru'); break; case 'Japanese': newLocale = Locale('ja'); break; case 'Punjabi': newLocale = Locale('pa'); break; case 'Tamil': newLocale = Locale('ta'); break; case 'Gujarati': newLocale = Locale('gu'); break; default: newLocale = Locale('en'); } SharedPreferences prefs = await SharedPreferences.getInstance(); await prefs.setString('languageCode', newLocale.languageCode); // 等待语言设置完成,确保翻译资源加载 await context.setLocale(newLocale); if (navigateToAgreementPage) { Navigator.of(context).pushReplacement( MaterialPageRoute(builder: (context) => AgreementPage()), ); } else { // 返回标记,通知上层页面语言已更改 Navigator.of(context).pop(true); } }
4. 完善语言选择页面的翻译文本
将页面中未翻译的文本改为使用.tr()方法:
// 原代码 Text("Choose your preferred languages") // 修改后 Text("Choose your preferred languages".tr())
5. 上层页面处理返回结果(可选)
如果是从其他页面打开语言选择页面,需要监听返回结果并触发自身重建:
final result = await Navigator.push( context, MaterialPageRoute(builder: (context) => LanguageSelectionScreen(navigateToAgreementPage: false)), ); if (result == true) { setState(() {}); // 触发页面重建,更新翻译内容 }
内容的提问来源于stack exchange,提问作者nxmo
相关产品推荐
相关产品推荐

