关于 flutter-setup-localization
面向 Flutter 开发者的本地化配置技能,介绍使用 ARB 文件与代码生成管理多语言文本。还涵盖 ICU 消息格式、RTL 布局和接入流程。
主要功能
- 01配置 Flutter 本地化依赖
- 02组织 ARB 翻译文件与元数据
- 03处理占位符、复数和选择格式
- 04适配 RTL 方向布局
- 05生成并接入本地化代码
适用场景
- 01为 Flutter 应用添加多语言支持
- 02管理带参数和复数的翻译
- 03适配阿拉伯语或希伯来语界面
- 04检查本地化配置与代码生成
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ dhruvanbhalara/ skills --skill flutter-setup-localization安装后在 Claude Code 中输入/flutter-setup-localization确认已加载。
详细介绍
目录
设置和配置
Flutter 使用 flutter_localizations 和 intl 软件包处理国际化。标准工作流会将 .arb 源文件编译成合成生成软件包,以便通过类型安全的代码进行访问。
1. 添加依赖项
在终端中运行以下命令,将所需依赖项添加到 pubspec.yaml:
flutter pub add flutter_localizations --sdk=flutter
flutter pub add intl:any
2. 启用代码生成
在 pubspec.yaml 文件的 flutter 部分中启用 generate 标志:
flutter:
generate: true
3. 创建配置文件
在项目根目录创建 l10n.yaml 文件,以定义本地化目录的输入和输出:
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
synthetic-package: true
4. 配置应用入口
导入生成的合成软件包,并将委托项和支持的区域设置注入 MaterialApp 或 CupertinoApp:
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
// ... inside the MaterialApp build method
return MaterialApp(
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('en'), // English
Locale('es'), // Spanish
],
home: const HomeScreen(),
);
ARB 文件结构和规则
应用资源包(.arb)文件采用标准 JSON 格式来表示键值对翻译字符串。
- 文件命名:将所有 ARB 文件放在
lib/l10n/中,并使用app_{locale}.arb模式(例如,app_en.arb、app_es.arb)。 - 元数据要求:模板文件(
app_en.arb)必须为每个翻译键包含相应的@key元数据对象,提供清晰的描述,以帮助翻译工作流。 - 键命名约定:统一使用
camelCase或 snake_case(例如,loginTitle或login_title)。采用简洁且描述性强的名称,指出字符串的使用位置。 - 严格隔离面向用户的文本:禁止在表现层硬编码任何面向用户的字符串。所有文本都必须通过 ARB 键提供。
ICU 消息格式
在 ARB 文件中使用 ICU 消息语法,以处理动态参数、基于数量的复数形式和条件选择。
1. 简单占位符
在花括号中定义参数名称,并在键元数据中注明其类型:
"helloUser": "Hello {name}",
"@helloUser": {
"description": "Greeting message containing user name",
"placeholders": {
"name": {
"type": "String",
"example": "Jane"
}
}
}
2. 复数形式
使用复数语法定义可计数项目的不同形式。other 情况为必填项:
"itemsCount": "{count, plural, =0{no items} =1{1 item} other{{count} items}}",
"@itemsCount": {
"description": "Inventory count message",
"placeholders": {
"count": {
"type": "num"
}
}
}
3. 选择
使用选择语法,根据参数匹配结果显示字符串(例如,类似枚举的值):
"pronoun": "{gender, select, male{he} female{she} other{they}}",
"@pronoun": {
"description": "Gendered pronoun selector",
"placeholders": {
"gender": {
"type": "String"
}
}
}
RTL(从右到左)布局支持
针对 RTL 语言(例如,阿拉伯语、希伯来语)进行本地化时,布局必须自动适配:
- 方向性 UI:使用
Directionality和可自动解析书写方向的小部件。 - 方向性间距:切勿使用左/右绝对坐标。始终优先使用方向性等效边距和内边距(例如,使用
EdgeInsetsDirectional.only(start: 16),而非EdgeInsets.only(left: 16))。 - 弹性对齐:在
MainAxisAlignment和CrossAxisAlignment弹性布局配置中,优先使用start和end,而非绝对的left或right值。
工作流:添加本地化支持
按照此清单实现并扩展多语言支持:
- 添加依赖包:安装
flutter_localizations和intl依赖包。 - 启用代码生成:在
pubspec.yaml中将generate: true标记设为启用。 - 配置 l10n:在项目根目录创建
l10n.yaml。 - 建立模板:创建
lib/l10n/app_en.arb,其中包含基准键和描述。 - 添加目标语言翻译:创建
lib/l10n/app_es.arb(以及其他目标语言文件),并添加翻译后的字符串。 - 生成代码:运行
flutter pub get或flutter gen-l10n以触发编译。 - 注入委托:更新
MaterialApp以定义本地化委托。 - 提供便捷的 context 访问方式:添加简洁的 context 扩展辅助方法,以便在组件中轻松获取字符串:
extension LocalizedContext on BuildContext { AppLocalizations get l10n => AppLocalizations.of(this)!; } - 测试布局边界:在目标 RTL/LTR 语言区域运行测试,确保布局和对齐依然得体。
示例
完整的基础 ARB 模板(lib/l10n/app_en.arb)
{
"loginHeader": "Welcome Back",
"@loginHeader": {
"description": "Main header visible on the authentication screen"
},
"greetingMessage": "Welcome, {username}!",
"@greetingMessage": {
"description": "Personalized welcome greeting",
"placeholders": {
"username": {
"type": "String",
"example": "Jane"
}
}
},
"cartItems": "{count, plural, =0{Your cart is empty} =1{1 item in your cart} other{{count} items in your cart}}",
"@cartItems": {
"description": "Cart items indicator showing quantity status",
"placeholders": {
"count": {
"type": "num"
}
}
}
}
使用 context 的组件
此示例使用自定义的 BuildContext 扩展辅助方法,轻松获取本地化内容。
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
// 1. Clean BuildContext extension helper
extension LocalizedContext on BuildContext {
AppLocalizations get l10n => AppLocalizations.of(this)!;
}
class DashboardHeader extends StatelessWidget {
final String username;
final int itemsCount;
const DashboardHeader({
super.key,
required this.username,
required this.itemsCount,
});
@override
Widget build(BuildContext context) {
// 2. Consume values cleanly via the extension shortcut
final l10n = context.l10n;
return Padding(
padding: const EdgeInsetsDirectional.only(start: 16.0, end: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
l10n.loginHeader,
style: Theme.of(context).textTheme.headlineMedium,
),
const SizedBox(height: 8),
Text(
l10n.greetingMessage(username),
style: Theme.of(context).textTheme.bodyLarge,
),
const SizedBox(height: 12),
Text(
l10n.cartItems(itemsCount),
style: Theme.of(context).textTheme.bodyMedium,
),
],
),
);
}
}
评论
支持 Markdown