Flutter 应用程序在使用 i18n Jetbrains 插件样板构建多语言 AppBar 时崩溃
Flutter app crashes building the AppBar with multi language using i18n Jetbrains plugin's boilerplate
之后为 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
内。不知道如何解开这个谜团。
编辑
我刚刚发现的另一件奇怪的事情:运行 在 --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" 本地化应该有效。
我向显示字符串的最小应用程序添加了所需的几行配置:
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
内。不知道如何解开这个谜团。
编辑
我刚刚发现的另一件奇怪的事情:运行 在 --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" 本地化应该有效。