在 Flutter 中使用多个本地化委托



我遇到了一个问题,我试图在MaterialApp中使用多个LocalizationsDelegates

我正在使用 Dartintl工具为我的标签提供翻译。当我有多个LocalizationsDelegates只有指定的一个时,第一个会获取转换后的值。下一个委托的标签,获取Intl.message()函数中提供的默认值。

简短、独立、正确的示例

我在 GitHub 上设置了一个最小的项目作为此问题的示例。

代码片段

MaterialApp中,我定义了一堆localizationsDelegates,包括两个特定于应用程序的:DogLocalizationsDelegateCatLocalizationsDelegate

MaterialApp(
// other properties
locale: Locale("en"),
localizationsDelegates: [
CatLocalizationsDelegate(),
DogLocalizationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
const Locale('en'),
const Locale('nl'),
],
);

委托具有相同的样板代码,但提供不同的标签。 以下是DogLocalizations及其DogLocalizationsDelegate的外观。

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'messages_all.dart';
class DogLocalizations {
static Future<DogLocalizations> load(Locale locale) {
final String name = locale.languageCode;
final String localeName = Intl.canonicalizedLocale(name);
return initializeMessages(localeName).then((_) {
Intl.defaultLocale = localeName;
return DogLocalizations();
});
}
static DogLocalizations of(BuildContext context) {
return Localizations.of<DogLocalizations>(context, DogLocalizations);
}
String get bark {
return Intl.message(
'<insert dog sound>',
name: 'bark',
);
}
}
class DogLocalizationsDelegate extends LocalizationsDelegate<DogLocalizations> {
const DogLocalizationsDelegate();
@override
bool isSupported(Locale locale) => ['en', 'nl'].contains(locale.languageCode);
@override
Future<DogLocalizations> load(Locale locale) => DogLocalizations.load(locale);
@override
bool shouldReload(DogLocalizationsDelegate old) => false;
}

CatLocalizations相同,但具有meow字符串获取器。GitHub 项目中的完整示例。

用于生成翻译文件的命令

我正在使用多个提取和生成命令,而不是在一个命令中有多个文件。这是因为我实际上在库(有自己的标签)和该库的使用者(也有自己的标签)上遇到了这个问题。

  1. 提取猫和狗的标签

flutter pub run intl_translation:extract_to_arb --output-dir=lib/cat_labels/gen lib/cat_labels/CatLabels.dart

flutter pub run intl_translation:extract_to_arb --output-dir=lib/dog_labels/gen lib/dog_labels/DogLabels.dart

  1. >将生成的intl_messages.arb翻译成两种语言文件

    • intl_en.arb
    • intl_nl.arb 然后将正确的翻译值添加到这些文件。
  2. 从 ARB 生成飞镖文件

flutter pub run intl_translation:generate_from_arb --output-dir=lib/cat_labels lib/cat_labels/CatLabels.dart lib/cat_labels/gen/intl_*.arb

flutter pub run intl_translation:generate_from_arb --output-dir=lib/dog_labels lib/dog_labels/DogLabels.dart lib/dog_labels/gen/intl_*.arb

问题

在此演示项目中,具有以下委托顺序:

// main.dart (line 20)
DogLocalizationsDelegate(),
CatLocalizationsDelegate(),

将给出bark标签的翻译,但不提供meow标签的翻译。

切换时:

// main.dart (line 20)
CatLocalizationsDelegate(),
DogLocalizationsDelegate(),

将给出meow标签的翻译,但不提供bark标签的翻译。

为什么有多个本地化代表

如果您想知道原因:我在库和该库的消费者应用程序中使用标签。重要的是要知道,因此(实际上)不可能在同一生成器命令中指定两个本地化文件。

据我所知,不,你不能像这样使用多个本地化委托。这是因为每个区域设置只能调用一次 intl 的initializeMessages

所以在你的例子中,一旦你的CatLocalizationsDelegate运行initializeMessagesDogLocalizationsDelegate的那个就不起作用了。这就是为什么你只看到翻译Meow!而不是Dog的翻译,或者任何一个先运行它的人。

如需更多阅读,请查看 https://phrase.com/blog/posts/how-to-internationalize-a-flutter-app/,请在 https://github.com/flutter/flutter/issues/41437 分享反馈。

您可以使用multiple_localizations包。 它对我有用

我在这里找到了一个带有专用颤振包的解决方案:multiple_localization

最新更新