Flutter国际化插件i18n的使用
Flutter国际化插件i18n的使用
简介
i18n 是一个用于Dart和Flutter的简单国际化包。此包支持热重载,并已在最新的Flutter版本上进行了测试。你可以将消息写入YAML文件,让这个包自动生成方便使用的Dart类。
概述
YAML文件到Dart类的转换
示例:YAML文件
lib/messages.i18n.yaml
button:
  save: Save
  load: Load
users:
  welcome(String name): "Hello $name!"
  logout: Logout
生成的Dart类
class Messages {
    const Messages();
    ButtonMessages get button => ButtonExampleMessages(this);
    UsersMessages get users => UsersExampleMessages(this);
}
class ButtonMessages {
    final Messages _parent;
    const ButtonMessages(this._parent);
    String get save => "Save";
    String get load => "Load";
}
class UsersMessages {
    final Messages _parent;
    const UsersMessages(this._parent);
    String get logout => "Logout";
    String welcome(String name) => "Hello $name!";
}
使用示例
Messages m = Messages();
print(m.users.welcome('World'));
// 输出: Hello World!
动机与目标
- 国际化应该在编译时进行检查。
- 消息键应该是方法而不是任意字符串。
- 支持参数化消息。
- 消息应按主题分组。
- 利用Dart的字符串插值功能。
- 支持build_runner和代码生成。
解决方案
写入YAML文件
默认消息
messages.i18n.yaml (默认消息):
generic:
  ok: OK
  done: DONE
invoice:
  create: Create invoice
  delete: Delete invoice
德语翻译
messages_de.i18n.yaml (_de = German translation)
generic:
  ok: OK
  done: ERLEDIGT
invoice:
  create: Rechnung erstellen
  delete: Rechnung löschen
使用生成的类
Messages m = Messages();
print(m.generic.ok); // 输出: OK
print(m.generic.done); // 输出: DONE
m = Messages_de();
print(m.generic.ok); // 输出: OK
print(m.generic.done); // 输出: ERLEDIGT
参数和复数形式
示例:带有参数的消息
invoice:
  create: Create invoice
  delete: Delete invoice
  help: "Use this function
  to generate new invoices and stuff.
  Awesome!"
  count(int cnt): "You have created $cnt ${_plural(cnt, one:'invoice', many:'invoices')}."
apples:
  _apples(int cnt): "${_plural(cnt, one:'apple', many:'apples')}"
  count(int cnt): "You have eaten $cnt ${_apples(cnt)}."
生成的类
class Messages {
    const Messages();
    InvoiceMessages get invoice => InvoiceExampleMessages(this);        
    ApplesMessages get apples => ApplesExampleMessages(this);
}
class InvoiceMessages {
    final Messages _parent;
    const InvoiceMessages(this._parent);
    String get create => "Create invoice";
    String get help => "Use this function to generate new invoices and stuff. Awesome!";
    String get delete => "Delete invoice";
    String count(int cnt) => "You have created $cnt ${_plural(cnt, one:'invoice', many:'invoices')}.";
}
class ApplesMessages {
    final Messages _parent;
    const ApplesMessages(this._parent);
    String _apples(int cnt) => "${_plural(cnt, one:'apple', many:'apples')}";
    String count(int cnt) => "You have eaten $cnt ${_apples(cnt)}.";
}         
复数函数
String _plural(int count, {String zero, String one, String two, String few, String many, String other})
String _cardinal(int count, {String zero, String one, String two, String few, String many, String other})
String _ordinal(int count, {String zero, String one, String two, String few, String many, String other})
如何使用生成的类
选择使用哪种翻译(如 Messages_de 或 Messages_hu)取决于你。该包仅生成消息类。
示例代码
import 'messages.i18n.dart';
import 'messages_de.i18n.dart' as de;
void main() async {
  Messages m = Messages();
  print(m.apples.count(1));
  print(m.apples.count(2));
  print(m.apples.count(5));
  m = de.Messages_de(); // ExampleMessages_de 继承自 Messages
  print(m.apples.count(1));
  print(m.apples.count(2));
  print(m.apples.count(5));    
}
如何在Flutter中使用
创建YAML文件
lib/messages/foo.i18n.yaml
修改 pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  i18n: any
  ...
dev_dependencies:
  build_runner: any
  flutter_test:
    sdk: flutter
运行生成器
flutter packages pub run build_runner watch
导入并使用生成的消息
import 'packages:my_app/messages/foo.i18n.dart'
...
Foo m = Foo();
return Text(m.bar);
...
自定义复数形式
目前,该包仅正确处理英语和捷克语的复数形式。你可以通过实现自己的语言规则来扩展支持。
示例:注册德语复数规则
i18n.registerResolver('de', (int count, i18n.QuantityType type) {
  if (type == i18n.QuantityType.cardinal && count == 1) {
    return i18n.QuantityCategory.one;
  }
  return i18n.QuantityCategory.other;
});
参考链接
希望这些信息能帮助你在Flutter项目中顺利实现国际化!如果有任何问题或需要进一步的帮助,请随时提问。
更多关于Flutter国际化插件i18n的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter国际化插件i18n的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter应用中使用flutter_i18n插件来实现国际化的代码示例。这个示例将涵盖基本的设置、资源文件创建和使用。
1. 添加依赖
首先,你需要在pubspec.yaml文件中添加flutter_i18n的依赖:
dependencies:
  flutter:
    sdk: flutter
  flutter_i18n: ^0.19.0  # 请检查最新版本号
然后运行flutter pub get来安装依赖。
2. 配置flutter_i18n
在你的Flutter项目根目录下创建一个名为assets/i18n的文件夹,用于存放翻译文件。
3. 创建翻译文件
在assets/i18n文件夹中,为每个支持的语言创建对应的JSON文件。例如:
- en.json(英文)
- zh.json(中文)
en.json内容示例:
{
  "welcome_message": "Welcome to our app!",
  "goodbye_message": "Goodbye!"
}
zh.json内容示例:
{
  "welcome_message": "欢迎来到我们的应用!",
  "goodbye_message": "再见!"
}
4. 初始化flutter_i18n
在你的main.dart文件中,初始化flutter_i18n:
import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.dart';
void main() {
  // 初始化flutter_i18n
  FlutterI18nDelegate delegate = FlutterI18nDelegate(
    fallbackLocale: Locale("en", "US"), // 默认语言
    translationAssets: const ["assets/i18n"] // 翻译文件路径
  );
  runApp(
    MaterialApp(
      home: MyHomePage(),
      localizationsDelegates: [
        delegate.buildLocalizationsDelegate(),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: delegate.supportedLocales,
      locale: delegate.currentLocale,
      localeResolutionCallback: (locale, supportedLocales) {
        // 根据用户设置或系统语言选择语言
        for (var supportedLocale in supportedLocales) {
          if (supportedLocale.languageCode == locale?.languageCode ||
              supportedLocale.countryCode == locale?.countryCode) {
            return supportedLocale;
          }
        }
        return supportedLocales.first;
      },
    ),
  );
}
class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    FlutterI18n flutterI18n = FlutterI18n.instance;
    return Scaffold(
      appBar: AppBar(
        title: Text(flutterI18n.translate("welcome_message")),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(flutterI18n.translate("welcome_message")),
            ElevatedButton(
              onPressed: () {
                // 切换语言示例
                FlutterI18nDelegate delegate =
                    Localizations.localeOf(context).languageCode == "en"
                        ? FlutterI18nDelegate(
                            fallbackLocale: Locale("zh", "CN"),
                            translationAssets: const ["assets/i18n"])
                        : FlutterI18nDelegate(
                            fallbackLocale: Locale("en", "US"),
                            translationAssets: const ["assets/i18n"]);
                delegate.loadTranslations();
                delegate.setLocale(Localizations.localeOf(context));
                // 更新MaterialApp的locale
                MaterialApp.router(
                  routeInformationParser: Router.routeInformationParser,
                  routerDelegate: MyRouterDelegate(),
                  locale: delegate.currentLocale,
                  localizationsDelegates: [
                    delegate.buildLocalizationsDelegate(),
                    GlobalMaterialLocalizations.delegate,
                    GlobalWidgetsLocalizations.delegate,
                  ],
                  supportedLocales: delegate.supportedLocales,
                ).build(context);
              },
              child: Text(flutterI18n.translate("goodbye_message")),
            ),
          ],
        ),
      ),
    );
  }
}
注意事项
- 重启应用:切换语言时,由于MaterialApp需要重新构建,实际应用中可能需要使用更优雅的方法来处理语言切换,例如使用Provider或Riverpod等状态管理库。
- 热重载:在开发过程中,确保在更改翻译文件后执行热重载,以便看到更改的效果。
以上代码提供了一个基本的框架,展示了如何在Flutter应用中使用flutter_i18n插件来实现国际化。根据你的具体需求,你可能需要添加更多的翻译文件和逻辑来处理不同的语言设置。
 
        
       
             
             
            

