You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 18:48:10