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

Flutter+GetX国际化异常:设置localizationsDelegates触发UnsupportedError

问题原因分析
  • 添加localizationsDelegates时报错:GlobalMaterialLocalizations.delegates是Flutter提供的不可修改列表,GetMaterialApp内部会尝试扩展传入的代理集合,直接赋值这个不可变列表会触发"修改不可修改集合"的错误。
  • 移除localizationsDelegates后TabBar报错:TabBar依赖MaterialLocalizations提供的本地化文本(如标签切换提示语),未配置正确代理时,Flutter无法找到对应的实例,从而抛出异常。
  • 硬编码en_US能运行:Flutter默认内置英文的MaterialLocalizations实现,无需额外代理即可工作,但印尼语没有默认实现,必须通过正确配置加载。
解决方案

1. 正确配置GetMaterialApp的本地化代理

不要直接赋值GlobalMaterialLocalizations.delegates,而是合并GetX代理与原生代理,同时启用GetX国际化功能:
修改main.dart中的GetMaterialApp配置:

return GetMaterialApp(
  title: "MyApp",
  initialRoute: AppPages.INITIAL,
  getPages: AppPages.routes,
  themeMode: ThemeMode.dark,
  theme: MyAppTheme.light,
  darkTheme: MyAppTheme.dark,
  debugShowCheckedModeBanner: false,
  translations: AppTranslations(), // 取消注释,启用GetX国际化
  locale: EnvService.instance.defaultLocale, // 从EnvService获取默认Locale,替代硬编码
  fallbackLocale: const Locale('en', 'US'),
  supportedLocales: const [
    Locale('en', 'US'),
    Locale('id', 'ID'),
  ],
  // 合并原生代理与GetX代理
  localizationsDelegates: [
    ...GlobalMaterialLocalizations.delegates,
    GetLocalizations.delegate,
  ],
);

2. 修复IntlService的初始化逻辑

当前IntlService.init()在runApp前执行,此时Get.locale尚未初始化,且initializeDateFormatting需传入语言代码而非国家代码,修改如下:

class IntlService extends GetxService {
  static IntlService get instance => Get.find();

  final _currentLocale = Rx<Locale>(EnvService.instance.defaultLocale);

  @override
  void onInit() {
    super.onInit();
    // 监听GetX的Locale变化,动态更新格式化器
    ever(Get.locale, (Locale? newLocale) {
      if (newLocale != null) {
        _currentLocale.value = newLocale;
        _initDateFormatting(newLocale.languageCode);
      }
    });
    // 初始化默认格式
    _initDateFormatting(_currentLocale.value.languageCode);
  }

  Future<void> _initDateFormatting(String languageCode) async {
    await initializeDateFormatting(languageCode);
  }

  String formatCurrency(double number) {
    final formatter = NumberFormat.simpleCurrency(
      decimalDigits: 0,
      locale: _currentLocale.value.toLanguageTag(),
    );
    return formatter.format(number);
  }

  String formatDate(DateTime? dateTime, [String? format = 'yyyy-MM-dd']) {
    if (dateTime == null) {
      return '';
    }
    return DateFormat(format, _currentLocale.value.languageCode).format(dateTime);
  }
}

同时调整main.dart的初始化顺序,确保App启动后再初始化IntlService:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await Get.putAsync(() => EnvService().init());
  runApp(const MyApp());
  await Get.putAsync(() => IntlService().init());
}

3. 实现GetX国际化翻译类

确保AppTranslations正确继承Translations,提供印尼语与英文的映射:

class AppTranslations extends Translations {
  @override
  Map<String, Map<String, String>> get keys => {
        'en_US': {
          'tab_home': 'Home',
          // 补充其他英文翻译项
        },
        'id_ID': {
          'tab_home': 'Beranda',
          // 补充其他印尼语翻译项
        },
      };
}

4. 验证默认Locale配置

确认EnvService中defaultLocale的逻辑正确:当.env文件中DEFAULT_LOCALE为id时,返回Locale('id', 'ID'),否则返回英文Locale。

内容的提问来源于stack exchange,提问作者Yura

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 13:26:01