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

rryofs0p  于 2023-06-24  发布在  Flutter
关注(0)|答案(3)|浏览(158)

我遇到了一个问题,我试图在一个MaterialApp中使用多个LocalizationsDelegates
我正在使用Dart intl工具为我的标签提供翻译。当我有多个LocalizationsDelegates时,只有指定的第一个得到转换后的值。下一个委托的标签将获得Intl.message()函数中提供的默认值。

简短,自包含,正确示例

我已经建立了一个最小的项目作为这个问题的例子on 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 String getter。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

  • 将生成的intl_messages.arb转换为两种语言文件
  • Intl_en.arb
  • intl_nl.arb然后将正确的翻译值添加到这些文件中。
  • 从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(),

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

切换时:

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

将给予meow标签的翻译,但不会给出bark标签的翻译。

为什么要多个本地化委托

如果你想知道为什么:我在一个库中和该库的消费者应用程序中使用标签。重要需要知道的是,由于这一点,在同一个生成器命令中指定两个本地化文件是不可能的。

x8diyxa7

x8diyxa71#

从我所了解到的,不,你不能像这样使用多个本地化委托。这是因为intl的initializeMessages只能在每个区域设置中调用一次。
因此,在您的示例中,一旦您的CatLocalizationsDelegate运行initializeMessagesDogLocalizationsDelegateCatLocalizationsDelegate就没有效果了。这就是为什么你只能看到翻译Meow!,而不能看到Dog的,或者任何一个先运行它的。
如需更多阅读,请查看https://phrase.com/blog/posts/how-to-internationalize-a-flutter-app/,并在https://github.com/flutter/flutter/issues/41437上分享反馈。

jucafojl

jucafojl2#

您可以使用multiple_localizations包。对我很有效

z5btuh9x

z5btuh9x3#

我在这里找到了一个专门的Flutter包的解决方案:multiple_localization

相关问题