Flutter 应用程序在使用 i18n Jetbrains 插件样板构建多语言 AppBar 时崩溃

Flutter app crashes building the AppBar with multi language using i18n Jetbrains plugin's boilerplate

我在 official documentation.

之后为 Android Studio 使用 Flutter i18n 插件

我向显示字符串的最小应用程序添加了所需的几行配置:

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: [S.delegate],
      supportedLocales: S.delegate.supportedLocales,
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
//      appBar: AppBar(
//        title: Text("Hard-coded English string"),
//      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(S.of(context).string_that_should_be_internationalized),
          ],
        ),
      ),
    );
  }
}

这是有效的(该字符串实际上已翻译成我的 phone 系统语言)。但是每次调用构建时都会发出警告:

Warning: This application's locale, it_, is not supported by all of its
localization delegates.
> A MaterialLocalizations delegate that supports the it_ locale was not found.

尽管 S.delegate.supportedLocales[en_, it_] 并且所有 arb 文件都已正确配置。

我可以使 Scaffold 正文任意复杂并且行为保持不变(i18n 使用警告)。但是,如果我向 Scaffold 添加一个简单的 AppBar (即使 widged 不需要翻译),整个应用程序也会崩溃。 (例如,在上面的代码段中取消注释)

错误摘要:

I/flutter (11411): No MaterialLocalizations found.
I/flutter (11411): AppBar widgets require MaterialLocalizations to be provided by a Localizations widget ancestor.
I/flutter (11411): Localizations are used to generate many different messages, labels,and abbreviations which are used
I/flutter (11411): by the material library.
I/flutter (11411): To introduce a MaterialLocalizations, either use a  MaterialApp at the root of your application to
I/flutter (11411): include them automatically, or add a Localization widget with a MaterialLocalizations delegate.
I/flutter (11411): The specific widget that could not find a MaterialLocalizations ancestor was:
I/flutter (11411):   AppBar

框架抱怨我的 AppBar 没有 Localizations 小部件祖先 。但它实际上有,因为它在 MaterialApp 内。不知道如何解开这个谜团。

Full log

编辑
我刚刚发现的另一件奇怪的事情:运行 在 --release 模式下完全相同的应用程序摆脱了所有错误和警告;一切都被正确翻译,包括 AppBar.
仍然想知道为什么它在 --debug 模式下崩溃。

问题不在于样板代码或配置。

错误的意思是 "default system strings" 不支持语言 "it_"。 (特别是由于 AppBar 的一些默认工具提示而崩溃 -> 这就是如果显示 AppBar 它会崩溃的原因)。

据报道 您可以通过实施自己的 LocalizationsDelegate.

来解决问题

完全修复

class MaterialLocalizationItDelegate extends LocalizationsDelegate<MaterialLocalizations> {
  /// Here list supported country and language codes
  @override
  bool isSupported(Locale locale) => locale.languageCode == "it";
  /// Here create an instance of your [MaterialLocalizations] subclass
  @override
  Future<MaterialLocalizations> load(Locale locale) async => MaterialLocalizationIt();
  @override
  bool shouldReload(_) => false;
}

class MaterialLocalizationIt extends MaterialLocalizations {
  // alt-enter on intellij and implement many overrides (somthing like 57)
}

然后将您的代表添加到代表列表中:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: [S.delegate, MaterialLocalizationItDelegate()],  // <- append here
      supportedLocales: S.delegate.supportedLocales,
      home: MyHomePage(),
    );
  }
}

快速修复

在实施 57 次覆盖之前快速检查这是否对您有用的方法。
准确复制此代码:

class FallbackLocalizationDelegate extends LocalizationsDelegate<MaterialLocalizations> {
  @override
  bool isSupported(Locale locale) => true;
  @override
  Future<MaterialLocalizations> load(Locale locale) async => DefaultMaterialLocalizations();
  @override
  bool shouldReload(_) => false;
}

上面的 class 声称支持所有语言环境 (isSupported(Locale locale) => true) 并且只是 returns 默认 en_US 语言环境。
最后将其添加到您的代表列表中。

localizationsDelegates: [S.delegate, FallbackLocalizationDelegate()],  // <- append here

此快速修复会将所有默认系统字符串设置为英语,但您的 "custom" 本地化应该有效。