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
插件来实现国际化。根据你的具体需求,你可能需要添加更多的翻译文件和逻辑来处理不同的语言设置。