arb-dir: lib/l10n # .arb 文件存放的目录
template-arb-file: app_en.arb # 模板文件,通常是英文
output-localization-file: app_localizations.dart # 生成的本地化文件名称
```
创建 .arb 文件:在 lib/l10n 目录下创建 .arb 文件,每个文件对应一种语言。
app_en.arb (英文模板)
{
"@@locale": "en",
"helloWorld": "Hello World",
"greeting": "Hello {name}",
"@greeting": {
"placeholders": {
"name": {}
}
},
"pluralExample": "{count, plural, one{One item} other{{count} items}}"
}
app_zh.arb (中文)
{
"@@locale": "zh",
"helloWorld": "你好世界",
"greeting": "你好 {name}",
"pluralExample": "{count, plural, one{一个项目} other{{count} 个项目}}"
}
生成本地化代码:运行 flutter gen-l10n 命令(如果 flutter: generate: true 在 pubspec.yaml 中设置,则 flutter run 或 flutter build 会自动触发)。这会在 .dart_tool/flutter_gen/gen_l10n/ 目录下生成 app_localizations.dart 和其他相关文件。
在 MaterialApp 中配置:在 MaterialApp 中添加 localizationsDelegates 和 supportedLocales。
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
MaterialApp(
localizationsDelegates: const [
AppLocalizations.delegate, // 由 flutter gen-l10n 生成
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('en', ''), // English
Locale('zh', ''), // Chinese
],
// ...
);
在 Widget 中使用:通过 AppLocalizations.of(context) 访问本地化字符串。
Text(AppLocalizations.of(context)!.helloWorld);
Text(AppLocalizations.of(context)!.greeting("Alice"));
Text(AppLocalizations.of(context)!.pluralExample(1));
Text(AppLocalizations.of(context)!.pluralExample(5));
国际化和本地化是构建面向全球用户的应用程序的关键。通过 Flutter 提供的国际化支持,我们可以轻松地为应用添加多语言功能,提升用户体验。
案例:一个支持中英文切换的简单应用
我们将创建一个简单的 Flutter 应用,演示如何实现中英文文本的切换,以及如何处理带参数的字符串和复数形式。
步骤 1: 按照上述“实现国际化的步骤”配置项目
确保 pubspec.yaml、l10n.yaml 和 .arb 文件都已正确设置,并运行 flutter gen-l10n。
步骤 2: 创建 Flutter 应用 (lib/main.dart)
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; // 导入生成的本地化文件
import 'package:flutter_localizations/flutter_localizations.dart'; // 导入 Flutter 本地化委托
class LocalizationExampleScreen extends StatefulWidget {
const LocalizationExampleScreen({super.key});
@override
State<LocalizationExampleScreen> createState() => _LocalizationExampleScreenState();
}
class _LocalizationExampleScreenState extends State<LocalizationExampleScreen> {
int _itemCount = 0;
void _incrementItemCount() {
setState(() {
_itemCount++;
});
}
@override
Widget build(BuildContext context) {
// 获取当前本地化实例
final AppLocalizations? appLocalizations = AppLocalizations.of(context);
// 如果 appLocalizations 为 null,说明本地化未加载或配置错误,显示默认文本
if (appLocalizations == null) {
return const Scaffold(
appBar: AppBar(title: Text('Error')),
body: Center(child: Text('Localization not loaded.')),
);
}
return Scaffold(
appBar: AppBar(
title: Text(appLocalizations.helloWorld), // 使用本地化字符串作为标题
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
appLocalizations.greeting('Flutter User'), // 使用带参数的本地化字符串
style: const TextStyle(fontSize: 24),
),
const SizedBox(height: 20),
Text(
appLocalizations.pluralExample(_itemCount), // 使用复数形式的本地化字符串
style: const TextStyle(fontSize: 24),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: _incrementItemCount,
child: const Text('增加项目'),
),
const SizedBox(height: 20),
// 切换语言的按钮
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: () {
// 切换到英文
// 这需要重新启动 MaterialApp 或使用更高级的状态管理来改变 Locale
// 简单示例中,我们假设用户通过系统设置切换语言
// 实际应用中,可以通过 Provider 或 Bloc 来管理 Locale 状态
print('切换到英文 (需要重启应用或刷新 Locale)');
},
child: const Text('English'),
),
ElevatedButton(
onPressed: () {
// 切换到中文
print('切换到中文 (需要重启应用或刷新 Locale)');
},
child: const Text('中文'),
),
],
),
],
),
),
);
}
}
void main() {
runApp(MaterialApp(
home: const LocalizationExampleScreen(),
// 配置本地化委托和支持的语言环境
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('en', ''), // English
Locale('zh', ''), // Chinese
],
// 可以通过 locale 属性设置初始语言环境,或通过设备语言环境自动检测
// locale: const Locale('zh', ''),
));
}
案例分析:
flutter: generate: true:在 pubspec.yaml 中启用此选项后,Flutter 会自动生成本地化代码。l10n.yaml:配置 .arb 文件的位置和生成的 Dart 文件名。.arb 文件:JSON 格式的资源文件,键值对表示本地化字符串。{name} 是占位符,{count, plural, ...} 是复数规则。AppLocalizations.delegate:由 flutter gen-l10n 命令生成,负责加载应用程序自定义的本地化字符串。GlobalMaterialLocalizations.delegate 等:Flutter 框架提供的本地化委托,用于加载 Material Design 组件、Widget 和 Cupertino 组件的本地化字符串。supportedLocales:声明应用程序支持的所有语言环境。Flutter 会根据设备的语言环境,从这个列表中选择最匹配的语言。AppLocalizations.of(context)!:在 Widget 中,通过 AppLocalizations.of(context) 获取当前语言环境的本地化实例。由于 of(context) 可能返回 null(例如在 MaterialApp 之外调用),所以通常需要进行空安全检查或使用 ! 断言。appLocalizations.greeting('Flutter User'):调用生成的本地化方法,传入参数来填充占位符。appLocalizations.pluralExample(_itemCount):调用生成的本地化方法,传入计数器值,根据 .arb 文件中的复数规则返回正确的字符串。这个案例清晰地展示了 Flutter 国际化和本地化的基本流程和使用方法。通过这种方式,我们可以轻松地为 Flutter 应用添加多语言支持,使其能够更好地服务于全球用户。