Flutter国际化-动态字符串

28

我正在使用intl包将我的应用程序翻译成西班牙语。

locales.dart

class AppLocale {
...
   String get folder => Intl.message("Folder", name: 'folder');
...
}

messages_es.dart

class MessageLookup extends MessageLookupByLibrary {
      get localeName => 'es';

      final messages = _notInlinedMessages(_notInlinedMessages);
      static _notInlinedMessages(_) => <String, Function> {
            "folder": MessageLookupByLibrary.simpleMessage("Carpeta"),
      };
}

我使用以下代码进行调用:

AppLocale.of(context).folder

它正常运作。

但是,我需要创建“动态”字符串,例如:

"你好,{$name}"

然后,调用此字符串并传递该“name”作为参数,或类似的内容。它将会被翻译为西班牙语中的“Hola, {$name}”。

使用intl包是否可以实现这一点?

4个回答

62

如果你遵循官方的国际化文档,并在.arb文件中指定所有短语,你可以像这样使用参数:

{
    "greeting": "Hi, {name}!",
    "@greeting": {
        "description": "Greet the user by their name.",
        "placeholders": {
            "name": {
                "type": "String",
                "example": "Jane"
            }
        }
    }
}

当你编译你的代码时,像下面这样的一个函数将会被自动生成,并带有一个漂亮的文档块以供你的 IDE 工具提示使用:

  /// Greet the user by their name.
  ///
  /// In en, this message translates to:
  /// **'Hi, {name}!'**
  String greeting(String name);

那么你可以像这样使用它:

Text(AppLocalizations.of(context)!.greeting("Koos"))

对我来说,有趣的是placeholders块只需要在一个arb文件中存在(在我的情况下是intl_en.arb)。 - James Poulose
如何将这些值添加到其他本地化文件中,比如说app_es.arb? - Husam Alhwadi
@HusamAlhwadi,您可以通过相同的方式添加它们,但通常只有在主语言文件中添加它们才有意义,该文件将用作将其他语言翻译的指南,译者应熟悉主语言。 - Jannie Theunissen
@JannieTheunissen,感谢您的回复。我已经将它添加到了app_en.arb文件中,但这还不够(据我所知)。每个占位符中的键值都需要添加到其他arb文件中(在我的情况下,我有4种不同的语言)。应用程序正在运行,并且没有出现任何错误,但是没有进行任何翻译。您能否详细说明一下如何将{name}值添加到其他arb文件中? - Husam Alhwadi
我必须执行 flutter cleanflutter pub get 命令才能使更改生效。 - genericUser
显示剩余2条评论

15

intl包的README解释了在示例https://github.com/dart-lang/intl中,将消息包装在函数中的目的是允许其具有可用于结果的参数。允许使用受限制的Dart字符串插值形式来使用消息字符串,其中只能使用函数的参数,而且只能使用简单表达式。不能使用局部变量和带花括号的表达式,只有消息字符串可以进行插值。名称、desc、args和examples必须是文字量而且不能包含插值。只有args参数可以引用变量,并且它应该准确列出函数参数。如果您正在传递数字或日期并希望格式化它们,则必须在函数外进行格式化并将格式化后的字符串传递到消息中。

greetingMessage(name) => Intl.message(
      "Hello $name!",
      name: "greetingMessage",
      args: [name],
      desc: "Greet the user as they first open the application",
      examples: const {'name': "Emily"});
  print(greetingMessage('Dan'));
在这个部分之下,有更多复杂的例子,涉及到复数和性别的处理。

4
为了在翻译中使用占位符,您需要:
  • 将该占位符作为getter参数添加
  • 在翻译中提到该占位符,并加上$前缀(例如:$name
  • 在调用Intl.message时将占位符添加到args列表中
因此,完整的示例如下:
greetingMessage(name) => Intl.message(
  "Hello $name!",
  name: 'greetingMessage',
  args: [name]
);

0

请按照链接进行操作。完成所有步骤后,请在您的.arb文件中进行以下更改:

{  
  "title": "App Title",
  "helloWorld": "{name1} and {name2} must be different",
  "@helloWorld": {
        "description": "The conventional newborn programmer greeting",
        "placeholders": {
                    "name1": {
                        "type": "String"
                    },
                    "name2": {
                        "type": "String"
                    }
                }
      },
  "appInfo":  "Information about your app",
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接