Flutter国际化翻译插件intl_translation的使用
Flutter国际化翻译插件intl_translation的使用
简介
intl_translation
是一个用于从程序源代码中提取需要翻译的消息并生成翻译后的代码的工具。它与 intl
包配合使用,帮助开发者实现应用程序的国际化和本地化。intl_translation
是一个独立的包,因此不会为所有用户引入对 analyzer
的依赖。
提取和使用翻译消息
当你的程序中包含需要翻译的消息时,这些消息必须从程序源代码中提取出来,发送给翻译人员进行翻译,然后将翻译结果整合到程序中。
提取消息
要提取消息,可以运行 extract_to_arb.dart
程序。以下是一个示例命令:
dart run intl_translation:extract_to_arb --output-dir=target/directory \
my_program.dart more_of_my_program.dart
你可以使用通配符来提取多个文件中的消息。例如,要从路径 lib/**/*.dart
中的所有 Dart 文件提取消息,可以运行以下命令:
dart run intl_translation:extract_to_arb --output-dir=target/directory \
lib/**/*.dart
这将生成一个名为 intl_messages.arb
的文件,其中包含所有这些程序中的消息。ARB
(Application Resource Bundle)格式文件可以用于输入到翻译工具中,如 Localizely 或 Lyrebird。
生成翻译后的代码
翻译完成后,可以使用 generate_from_arb.dart
程序生成一组库文件,每个库文件对应一个语言环境。以下是一个示例命令:
dart run intl_translation:generate_from_arb --generated-file-prefix=<prefix> \
<my_dart_files> <translated_ARB_files>
这将生成一系列 Dart 库文件,每个文件对应一个语言环境,包含翻译后的版本。你的 Dart 库可以导入主文件,命名为 <prefix>messages_all.dart
,然后调用特定语言环境的初始化函数。一旦初始化完成,任何 Intl.message
调用都会自动打印翻译后的版本,而不是原始版本。
以下是一个示例代码片段,展示了如何在 Dart 代码中使用这些生成的库:
import 'my_prefix_messages_all.dart';
void main() async {
// 初始化特定语言环境的消息
await initializeMessages('zh_CN');
// 打印一些消息
printSomeMessages();
}
void printSomeMessages() {
// 使用 Intl.message 打印翻译后的消息
print(Intl.message('Hello, world!', name: 'helloWorld'));
}
示例项目
为了更好地理解 intl_translation
的使用,我们可以通过一个示例项目来演示其工作流程。
示例项目结构
假设我们有一个简单的 Flutter 项目,包含以下文件结构:
.
├── lib
│ ├── main.dart
│ └── messages_all.dart
├── target
│ └── directory
│ └── intl_messages.arb
└── pubspec.yaml
步骤 1:添加依赖
首先,在 pubspec.yaml
文件中添加 intl
和 intl_translation
依赖:
dependencies:
flutter:
sdk: flutter
intl: ^0.17.0
dev_dependencies:
flutter_test:
sdk: flutter
intl_translation: ^0.18.0
步骤 2:编写需要翻译的消息
在 lib/main.dart
中编写一些需要翻译的消息:
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'messages_all.dart';
void main() async {
// 初始化特定语言环境的消息
await initializeMessages('zh_CN');
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(Intl.message('Welcome to Flutter', name: 'welcomeMessage')),
),
body: Center(
child: Text(Intl.message('Hello, world!', name: 'helloWorld')),
),
);
}
}
步骤 3:提取消息
在项目根目录下运行以下命令,将需要翻译的消息提取到 target/directory/intl_messages.arb
文件中:
dart run intl_translation:extract_to_arb --output-dir=target/directory \
lib/main.dart
步骤 4:翻译消息
打开 target/directory/intl_messages.arb
文件,将其内容翻译成目标语言。例如,将英文翻译成中文:
{
"helloWorld": "你好,世界!",
"welcomeMessage": "欢迎来到 Flutter",
"@helloWorld": {
"description": "A simple greeting message"
},
"@welcomeMessage": {
"description": "A welcome message for the app"
}
}
步骤 5:生成翻译后的代码
保存翻译后的 intl_messages.arb
文件,并运行以下命令生成翻译后的 Dart 代码:
dart run intl_translation:generate_from_arb --generated-file-prefix=messages \
lib/main.dart target/directory/intl_messages.arb
这将在 lib/generated
目录下生成一系列文件,例如 messages_zh_CN.dart
,其中包含翻译后的消息。
步骤 6:运行应用
现在,你可以运行你的 Flutter 应用,它将显示翻译后的消息:
flutter run
更多关于Flutter国际化翻译插件intl_translation的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter国际化翻译插件intl_translation的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用intl_translation
插件进行国际化翻译的详细代码示例。
1. 添加依赖
首先,你需要在pubspec.yaml
文件中添加intl
和flutter_localizations
依赖:
dependencies:
flutter:
sdk: flutter
intl: ^0.17.0 # 请检查最新版本
dev_dependencies:
flutter_test:
sdk: flutter
intl_translation: ^0.17.10+1 # 请检查最新版本
2. 创建arb文件
在lib/l10n
目录下创建一个ARB(Application Resource Bundle)文件,例如messages_en.arb
和messages_zh.arb
。ARB文件用于定义不同语言的翻译内容。
messages_en.arb
{
"welcome_message": "Welcome to our app!",
"goodbye_message": "Goodbye!"
}
messages_zh.arb
{
"welcome_message": "欢迎来到我们的应用!",
"goodbye_message": "再见!"
}
3. 生成本地化文件
在项目根目录下创建一个名为tool
的目录,并在其中创建一个generate_localizations.dart
脚本,用于生成本地化文件。
generate_localizations.dart
import 'package:intl_translation/generate_localized.dart';
void main() {
generateLocalizedFiles(
templateArbFile: 'lib/l10n/messages_en.arb',
outputDirectory: 'lib/l10n/generated',
arbDir: 'lib/l10n',
mainDartFile: 'lib/main.dart',
className: 'S', // 这是生成的Localizations类的名称前缀
useDeferredLoading: true,
);
}
在pubspec.yaml
中,添加一个运行脚本:
scripts:
generate_localizations: dart tool/generate_localizations.dart
运行以下命令生成本地化文件:
flutter pub run script:generate_localizations
4. 使用生成的本地化文件
在lib/main.dart
中,导入生成的本地化文件并使用它们。
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 Example',
localizationsDelegates: [
S.delegate, // 使用生成的LocalizationsDelegate
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);
final S _local = S.of(context);
return Scaffold(
appBar: AppBar(
title: Text(_local.welcome_message),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(_local.welcome_message),
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ChangeLocaleScreen(),
),
);
},
child: Text('Change Locale'),
),
],
),
),
);
}
}
class ChangeLocaleScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Change Locale'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () {
Navigator.popAndPushNamed(context, '/', arguments: Locale('en', ''));
},
child: Text('English'),
),
ElevatedButton(
onPressed: () {
Navigator.popAndPushNamed(context, '/', arguments: Locale('zh', ''));
},
child: Text('中文'),
),
],
),
),
);
}
}
在上面的代码中,我们通过Navigator.popAndPushNamed
方法来改变应用的当前语言环境。注意,这里我们假设根路由/
是MyHomePage
。
5. 更新路由处理
确保在MaterialApp
中处理路由参数以更新语言环境:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Intl Example',
localizationsDelegates: [
S.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: S.delegate.supportedLocales,
onGenerateRoute: (RouteSettings settings) {
Locale locale = settings.arguments is Locale ? settings.arguments as Locale : Locale('en', '');
return MaterialPageRoute<void>(
settings: settings.copyWith(arguments: locale),
builder: (BuildContext context) {
return Localizations(
locale: locale,
child: MyHomePage(),
);
},
);
},
initialRoute: '/',
routes: {
'/': (context) => MyHomePage(),
},
);
}
}
注意,这里的路由处理逻辑仅作为示例,实际项目中可能需要更复杂的处理逻辑。
这样,你就完成了在Flutter项目中使用intl_translation
插件进行国际化翻译的基本设置。