Flutter国际化消息插件intl_messages的使用

发布于 1周前 作者 caililin 来自 Flutter

Flutter国际化消息插件intl_messages的使用

intl_messages 是一个简单且易于使用的库,用于实现Flutter应用的消息国际化和本地化(I18N)。它支持按包/模块组织消息、动态加载消息资源文件、全局通知语言环境变化以及注册/发现本地化消息。此外,它还提供了翻译工具,包括与OpenAI和ChatGPT的集成。

主要特性

  • 按包/模块组织消息:可以将不同的消息文件组织在不同的包或模块中。
  • 动态加载消息资源文件:可以根据当前的语言环境动态加载相应的消息文件。
  • 全局通知语言环境变化:当语言环境发生变化时,会触发全局通知。
  • 注册/发现本地化消息:自动发现并注册本地化消息文件。
  • 翻译工具:支持与OpenAI和ChatGPT集成,帮助进行翻译。

使用示例

1. 创建国际化文件

首先,创建两个国际化文件,分别对应英语和法语:

  • msgs-en.intl (英文):

    hello=Hello world! ## A description of the key.
    
  • msgs-fr.intl (法文):

    hello=Bonjour le monde!
    
2. Dart代码示例

接下来,在Dart代码中使用这些国际化文件:

import 'package:intl_messages/intl_messages.dart';

void main() async {
  // 创建一个IntlMessages实例,指定包名为"demo"
  var messages = IntlMessages.package("demo");

  // 创建一个资源发现器,指定消息文件的路径和扩展名
  IntlResourceDiscover discover = IntlResourceDiscover("assets/msgs-", ".intl");

  // 注册资源发现器,默认语言环境为'en'
  await messages.registerResourceDiscover(discover); // 默认语言环境: 'en',发现: assets/msgs-en.intl

  // 获取消息构建器
  MessageBuilder msgHello = messages.msg("hello");

  // 打印消息
  print(msgHello.build()); // 输出: Hello world!

  // 设置语言环境为'fr'
  await messages.setLocale('fr'); // 语言环境设置为: 'fr',发现: assets/msgs-fr.intl

  // 再次打印消息
  print(msgHello.build()); // 输出: Bonjour le monde!
}
3. 复数形式的使用

intl_messages 支持复数形式的消息。你可以在国际化文件中使用 {...} 块来定义复数条件,如 zeroonetwomany,并指定相应的变量名。

  • msgs-en.intl (英文):

    total_emails={zero[n]:No e-mails for $user.|one[n]:One e-mail for $user.|two[n]:A pair of e-mails for $user.|many[n]:Received $n e-mails for $user.}
    
  • Dart代码示例:

    import 'package:intl_messages/intl_messages.dart';
    
    void main() async {
      // 创建一个IntlMessages实例,指定包名为"demo-plural"
      var messages = IntlMessages.package("demo-plural");
    
      // 创建一个资源发现器,指定消息文件的路径和扩展名
      IntlResourceDiscover discover = IntlResourceDiscover("assets/msgs-", ".intl");
    
      // 注册资源发现器,默认语言环境为'en'
      await messages.registerResourceDiscover(discover); // 默认语言环境: 'en',发现: assets/msgs-en.intl
    
      // 获取消息构建器
      MessageBuilder msgEmail = messages.msg("total_emails");
    
      // 打印不同数量的邮件消息
      print(msgEmail.build({'n': 0, 'user': 'john@mail.com'})); // 输出: No e-mails for john@mail.com.
      print(msgEmail.build({'n': 1, 'user': 'john@mail.com'})); // 输出: One e-mail for john@mail.com.
      print(msgEmail.build({'n': 2, 'user': 'john@mail.com'})); // 输出: A pair of e-mails for john@mail.com.
      print(msgEmail.build({'n': 8, 'user': 'john@mail.com'})); // 输出: Received 8 e-mails for john@mail.com.
    }
    

CLI工具

intl_messages 还提供了一个命令行工具,可以帮助你检查、格式化和修复 .intl 文件。以下是几个常用的命令:

  • 检查 .intl 文件

    intl_messages check --ref msgs-en.intl -f msgs-fr.intl
    
  • 格式化 .intl 文件

    intl_messages format --ref msgs-en.intl -f msgs-fr.intl --overwrite
    
  • 使用 OpenAI 修复 .intl 文件

    intl_messages fix --ref msgs-en.intl -f msgs-fr.intl -t openai --overwrite
    

完整示例Demo

以下是一个完整的示例,展示了如何在一个Flutter应用中使用 intl_messages 进行国际化和本地化:

import 'package:flutter/material.dart';
import 'package:intl_messages/intl_messages.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final IntlMessagesLoader intlMessagesLoader =
      IntlMessagesLoader('example', 'example/i18n/msgs-');

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter I18N Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final App app = App();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(app.messages.msg('welcome').build()),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              app.messages.msg('language').build(),
              style: TextStyle(fontSize: 24),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () async {
                await app.messages.setLocale('fr');
                setState(() {});
              },
              child: Text('切换到法语'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () async {
                await app.messages.setLocale('en');
                setState(() {});
              },
              child: Text('切换到英语'),
            ),
          ],
        ),
      ),
    );
  }
}

class App {
  final IntlMessagesLoader intlMessagesLoader =
      IntlMessagesLoader('example', 'example/i18n/msgs-');

  IntlMessages get messages => intlMessagesLoader.intlMessages;

  String get msgWelcome => messages.msg('welcome').build();

  String get msgLanguage => messages.msg('language').build();

  String msgTotalEmails(int n, String user) =>
      messages.msg('total_emails').build({'n': n, 'user': user});

  final String? forceLocale;

  App([this.forceLocale]) {
    if (intlMessagesLoader.isLoaded) {
      run();
    } else {
      intlMessagesLoader.onLoad.listen((event) => run());
    }
  }

  void run() {
    if (forceLocale != null) {
      messages.setLocale(forceLocale);
    }

    print('----------------------------- ${messages.currentLocale}');

    print(msgWelcome);

    print('$msgLanguage: ${messages.currentLocale!.language}');

    for (var i = 0; i <= 4; i++) {
      print('$i> ${msgTotalEmails(i, 'Joe')}');
    }
  }
}

更多关于Flutter国际化消息插件intl_messages的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter国际化消息插件intl_messages的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用intl_messages插件来实现国际化的示例代码。请注意,intl_messages实际上可能指的是Flutter的intl包,它通常用于处理国际化和本地化。以下是如何设置和使用它的一个示例。

步骤 1: 添加依赖

首先,在你的pubspec.yaml文件中添加intl依赖:

dependencies:
  flutter:
    sdk: flutter
  intl: ^0.17.0 # 请根据需要检查最新版本

然后运行flutter pub get来安装依赖。

步骤 2: 创建国际化文件

创建一个名为messages_all.dart的文件,它将包含所有的国际化消息。你还需要为每个支持的语言创建一个arb文件,例如messages_en.arbmessages_zh.arb

messages_en.arb

{
  "greeting": "Hello, World!",
  "farewell": "Goodbye!"
}

messages_zh.arb

{
  "greeting": "你好,世界!",
  "farewell": "再见!"
}

步骤 3: 生成本地化文件

使用intl_translation工具来生成Dart本地化文件。首先,添加intl_translationdev_dependencies

dev_dependencies:
  build_runner: ^2.0.0
  intl_translation: ^0.17.10+1 # 请根据需要检查最新版本

然后运行以下命令来生成本地化Dart文件:

flutter pub run intl_translation:extract_to_arb --output-dir=lib/l10n lib/main.dart
flutter pub run intl_translation:generate_from_arb --output-dir=lib/l10n --gen-l10n-package=your_app_name,lib/l10n/messages_all.dart lib/l10n/*.arb

注意替换your_app_name为你的Flutter项目的实际包名。

步骤 4: 使用国际化消息

在你的Flutter应用中,使用生成的本地化文件来加载和显示消息。

lib/l10n/messages_all.dart (自动生成)

这个文件会被自动生成,你不需要手动编辑它。

lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'l10n/messages_all.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Intl Demo',
      localizationsDelegates: [
        S.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: S.delegate.supportedLocales,
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Locale _locale;

  @override
  Widget build(BuildContext context) {
    _locale = Localizations.localeOf(context);
    S.load(context);

    return Scaffold(
      appBar: AppBar(
        title: Text(S.of(context).greeting),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(S.of(context).greeting),
            ElevatedButton(
              onPressed: () {
                setState(() {
                  _locale = _locale.languageCode == 'en' ? Locale('zh') : Locale('en');
                  // 更新Locale
                  final localizations = Localizations.of<Localizations>(context, nullOk: true);
                  if (localizations != null) {
                    localizations.setLocale(_locale);
                  }
                });
              },
              child: Text('Switch Language'),
            ),
            Text(S.of(context).farewell),
          ],
        ),
      ),
    );
  }
}

解释

  1. 依赖和工具:我们使用intl包来处理国际化,并使用intl_translation工具从ARB文件生成Dart代码。
  2. ARB文件:ARB文件包含每种语言的消息。
  3. 生成代码:使用intl_translation工具生成Dart本地化文件。
  4. 应用代码:在MaterialApp中设置localizationsDelegatessupportedLocales,并在UI中使用S.of(context)来访问本地化消息。

这个示例展示了如何在Flutter应用中使用intl包来实现基本的国际化功能。你可以根据需要扩展这个示例以支持更多的语言和消息。

回到顶部