关于 internationalization
面向 Flutter 开发者的国际化与本地化指南,采用 Flutter 内置本地化系统和 ARB 文件管理翻译。内容包括文案访问、可复用组件、RTL 布局、复数形式和新增语言流程。
主要功能
- 01使用 ARB 文件作为翻译源
- 02通过 `context.l10n` 访问本地化文案
- 03可复用组件接收本地化字符串参数
- 04使用方向性布局适配 RTL
- 05支持 ICU 复数语法
适用场景
- 01为 Flutter 应用配置本地化流程
- 02添加语言及对应翻译
- 03为共享组件传入本地化文案
- 04处理 RTL 布局和本地化错误消息
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ verygoodopensource/ vgv-ai-flutter-plugin --skill internationalization安装后在 Claude Code 中输入/internationalization确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlreferences/backend.mddirectionality.mdsetup.md详细介绍
国际化
使用 Flutter 内置本地化系统,并以 ARB 文件作为唯一事实来源的 Flutter 应用国际化(i18n)与本地化(l10n)最佳实践。
核心规范
所有国际化工作均须遵循以下规范:
- 绝不硬编码面向用户的字符串——所有文本都必须通过 l10n 系统处理
- 使用 Flutter 内置本地化系统——使用
flutter_localizations+intl,绝不使用第三方 i18n 库 - ARB 文件是所有翻译的唯一事实来源
- 使用
BuildContext扩展简化 l10n 访问——使用context.l10n,而不是AppLocalizations.of(context) - 将本地化字符串作为参数传递给可复用组件——绝不要让共享组件直接依赖
AppLocalizations - 使用
EdgeInsetsDirectional(start/end),而不是EdgeInsets(left/right)——确保 RTL 语言中的布局正确 - 正确处理 RTL 布局——使用支持方向性的组件处理内边距、定位和对齐
- 尽早实现 i18n——即使最初只计划支持一种语言,额外工作也很少,长期收益却很大
- Dart 3.13 主构造函数——若基线版本为 Dart 3.13+,应将可复用组件的本地化字符串字段声明为主构造函数声明参数(
class const ConfirmDialog({required final String title, super.key}) extends StatelessWidget),而不是使用this.field;低于 3.13 时才保留传统形式
设置流程和 ARB 文件格式
将 flutter_localizations 和 intl 添加为依赖项,在 pubspec.yaml 中启用 generate: true,配置 l10n.yaml,在 lib/l10n/arb/ 中创建 ARB 文件,运行 flutter gen-l10n,并通过 localizationsDelegates 和 supportedLocales 配置 MaterialApp。ARB 文件支持简单字符串、占位符和 ICU 复数语法。
BuildContext 扩展
创建一个扩展,以便在整个代码库中便捷地访问 l10n:
extension AppLocalizationsX on BuildContext {
AppLocalizations get l10n => AppLocalizations.of(this);
}
用法:
// Preferred
Text(context.l10n.helloWorld);
// Avoid
Text(AppLocalizations.of(context).helloWorld);
可复用组件策略
位于独立软件包中的共享组件不应直接依赖 AppLocalizations。应改为将本地化字符串作为构造函数参数传入:
当有人要求在共享软件包中添加 AppLocalizations 时,应拒绝并说明原因——该软件包将携带自己的翻译,所有使用它的应用都会受其限制——然后将其组件改写为以 final String 构造函数参数接收标签,并展示调用处如何传入 context.l10n。两者都要以 Dart 代码给出;只用文字描述改动会让调用方不得不猜测函数签名。
// Shared widget — no l10n dependency
class const ConfirmDialog({
required final String title,
required final String message,
required final String confirmLabel,
required final String cancelLabel,
super.key,
}) extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text(title),
content: Text(message),
actions: [
TextButton(onPressed: () => Navigator.pop(context), child: Text(cancelLabel)),
FilledButton(onPressed: () => Navigator.pop(context, true), child: Text(confirmLabel)),
],
);
}
}
// App-level usage — passes localized strings
showDialog<bool>(
context: context,
builder: (_) => ConfirmDialog(
title: context.l10n.deleteTitle,
message: context.l10n.deleteMessage,
confirmLabel: context.l10n.confirm,
cancelLabel: context.l10n.cancel,
),
);
文本方向性
所有内边距和外边距都应使用 EdgeInsetsDirectional(start/end),而不是 EdgeInsets(left/right)。对于支持 RTL 的布局,应使用支持方向性的组件变体(PositionedDirectional、AlignDirectional、BorderDirectional)。图标会在 RTL 中自动镜像;图片则需要设置 matchTextDirection: true。
后端注意事项
后端内容应按语言区域存储翻译,并要求客户端传递用户的语言区域。对于错误消息,应在前端将 HTTP 状态码或自定义后端错误常量映射到 l10n 键。
常见模式
添加新的语言区域
- 在
lib/l10n/arb/中创建app_<locale>.arb(例如,app_fr.arb) - 为模板 ARB 文件中的所有键添加翻译
- 运行
flutter gen-l10n - 新语言区域会通过
AppLocalizations.supportedLocales自动启用
添加新字符串
- 将键值对添加到模板 ARB 文件(
app_en.arb)中 - 添加
@key元数据;如有需要,注明描述和占位符 - 在所有其他 ARB 文件中添加翻译
- 运行
flutter gen-l10n - 通过
context.l10n.newKey使用
复数形式
- 使用 ICU 消息语法在模板 ARB 文件中定义复数字符串
- 提供
"type": "int"占位符元数据 - 在所有语言区域的 ARB 文件中添加复数形式
- 通过
context.l10n.itemCount(items.length)使用
附加资源
- references/setup.md — 完整的分步设置流程和 ARB 文件格式示例
- references/directionality.md — 视觉与方向性组件、图标/图像镜像,以及 Material 双向性标准
- references/backend.md — 多语言内容存储和错误消息本地化