在 Flutter 中使用多个 LocalizationsDelegates

dum*_*azy 10 internationalization flutter dart-intl

我正面临一个问题,我试图LocalizationsDelegatesMaterialApp.

我正在使用 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'),
  ],
);
Run Code Online (Sandbox Code Playgroud)

代表具有相同的样板代码,但提供不同的标签。这是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;
}
Run Code Online (Sandbox Code Playgroud)

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 生成 dart 文件

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(),
Run Code Online (Sandbox Code Playgroud)

将为bark标签提供翻译,但不会为meow标签提供翻译。

切换它:

// main.dart (line 20)
CatLocalizationsDelegate(),
DogLocalizationsDelegate(),
Run Code Online (Sandbox Code Playgroud)

将为meow标签提供翻译,但不会为bark标签提供翻译。

为什么有多个本地化代表

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

TWL*_*TWL 5

据我所知,不,您不能像这样使用多个本地化委托。这是因为 intl\xe2\x80\x99sinitializeMessages每个语言环境只能调用一次。

\n\n

因此,在您的示例中,一旦您CatLocalizationsDelegate运行initializeMessages, 则DogLocalizationsDelegate没有效果。这就是为什么你只能看到翻译Meow!而看不到 Dog\xe2\x80\x99s 或第一个运行它的人的原因。

\n\n

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

\n