flutter-internationalization
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFlutter Internationalization
Flutter应用国际化
Overview
概述
Comprehensive guide for adding internationalization (i18n) to Flutter applications. Covers setup, configuration, message management, number/date formatting, and advanced topics like locale override and custom language support.
为Flutter应用添加国际化(i18n)的全面指南,涵盖设置、配置、消息管理、数字/日期格式化,以及Locale覆盖、自定义语言支持等高级主题。
Quick Start
快速入门
Choose approach based on app needs:
gen-l10n (Recommended) - Modern, automated, code generation
- Best for: Most new projects, teams, complex apps
- Uses: ARB files, automated code generation
- See: Setup gen-l10n
intl package - Manual control, code-based
- Best for: Simple apps, legacy projects, full control
- Uses: code, manual translation files
Intl.message() - See: Setup intl package
Manual/Custom - Maximum flexibility
- Best for: Very simple apps, custom workflows
- Uses: Direct Map-based lookups
- See: Custom localizations
根据应用需求选择合适的方案:
gen-l10n(推荐) - 现代化、自动化的代码生成方案
- 适用场景:大多数新项目、团队协作、复杂应用
- 使用工具:ARB文件、自动化代码生成
- 查看:gen-l10n设置
intl包 - 手动控制、基于代码的方案
- 适用场景:简单应用、遗留项目、需要完全控制权的场景
- 使用工具:代码、手动翻译文件
Intl.message() - 查看:intl包设置
手动/自定义方案 - 最大灵活性
- 适用场景:极简应用、自定义工作流
- 使用工具:直接基于Map的查找
- 查看:自定义本地化
Setup gen-l10n
gen-l10n设置
1. Add Dependencies
1. 添加依赖
Update :
pubspec.yamlyaml
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: anyRun:
bash
flutter pub add flutter_localizations --sdk=flutter
flutter pub add intl:any更新:
pubspec.yamlyaml
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: any运行以下命令:
bash
flutter pub add flutter_localizations --sdk=flutter
flutter pub add intl:any2. Enable Code Generation
2. 启用代码生成
Add to :
pubspec.yamlyaml
flutter:
generate: true在中添加:
pubspec.yamlyaml
flutter:
generate: true3. Configure l10n.yaml
3. 配置l10n.yaml
Create in project root:
l10n.yamlyaml
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dartFor advanced options, see l10n-config.md.
在项目根目录创建文件:
l10n.yamlyaml
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart如需高级配置选项,请查看l10n-config.md。
4. Create ARB Files
4. 创建ARB文件
Create directory .
lib/l10n/Template file :
lib/l10n/app_en.arbjson
{
"helloWorld": "Hello World!",
"@helloWorld": {
"description": "Greeting message"
}
}Translation file :
lib/l10n/app_es.arbjson
{
"helloWorld": "¡Hola Mundo!"
}For complete ARB format, see arb-format.md.
创建目录。
lib/l10n/模板文件 :
lib/l10n/app_en.arbjson
{
"helloWorld": "Hello World!",
"@helloWorld": {
"description": "Greeting message"
}
}翻译文件 :
lib/l10n/app_es.arbjson
{
"helloWorld": "¡Hola Mundo!"
}如需了解完整的ARB文件格式,请查看arb-format.md。
5. Generate Code
5. 生成代码
Run:
bash
flutter gen-l10nOr run app to trigger auto-generation:
bash
flutter run运行以下命令:
bash
flutter gen-l10n或运行应用触发自动生成:
bash
flutter run6. Configure MaterialApp
6. 配置MaterialApp
Import and setup:
dart
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'l10n/app_localizations.dart';
MaterialApp(
localizationsDelegates: [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
Locale('en'),
Locale('es'),
],
home: MyHomePage(),
)导入并设置:
dart
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'l10n/app_localizations.dart';
MaterialApp(
localizationsDelegates: [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
Locale('en'),
Locale('es'),
],
home: MyHomePage(),
)7. Use Localizations
7. 使用本地化内容
Access in widgets:
dart
Text(AppLocalizations.of(context)!.helloWorld)在组件中访问:
dart
Text(AppLocalizations.of(context)!.helloWorld)Message Types
消息类型
Simple Messages
简单消息
No parameters:
json
{
"welcome": "Welcome to our app",
"@welcome": {
"description": "Welcome message"
}
}无参数:
json
{
"welcome": "Welcome to our app",
"@welcome": {
"description": "Welcome message"
}
}Placeholder Messages
占位符消息
With parameters:
json
{
"greeting": "Hello {userName}!",
"@greeting": {
"description": "Personalized greeting",
"placeholders": {
"userName": {
"type": "String",
"example": "Alice"
}
}
}
}Use in code:
dart
Text(AppLocalizations.of(context)!.greeting('Alice'))带参数:
json
{
"greeting": "Hello {userName}!",
"@greeting": {
"description": "Personalized greeting",
"placeholders": {
"userName": {
"type": "String",
"example": "Alice"
}
}
}
}在代码中使用:
dart
Text(AppLocalizations.of(context)!.greeting('Alice'))Plural Messages
复数消息
Based on count:
json
{
"itemCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}",
"@itemCount": {
"placeholders": {
"count": {
"type": "int"
}
}
}
}Use in code:
dart
Text(AppLocalizations.of(context)!.itemCount(5))基于数量:
json
{
"itemCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}",
"@itemCount": {
"placeholders": {
"count": {
"type": "int"
}
}
}
}在代码中使用:
dart
Text(AppLocalizations.of(context)!.itemCount(5))Select Messages
选择消息
Based on string value:
json
{
"pronoun": "{gender, select, male{he} female{she} other{they}}",
"@pronoun": {
"placeholders": {
"gender": {
"type": "String"
}
}
}
}Use in code:
dart
Text(AppLocalizations.of(context)!.pronoun('male'))基于字符串值:
json
{
"pronoun": "{gender, select, male{he} female{she} other{they}}",
"@pronoun": {
"placeholders": {
"gender": {
"type": "String"
}
}
}
}在代码中使用:
dart
Text(AppLocalizations.of(context)!.pronoun('male'))Number and Date Formatting
数字与日期格式化
Numbers
数字
Format numbers automatically:
json
{
"price": "Price: {value}",
"@price": {
"placeholders": {
"value": {
"type": "int",
"format": "simpleCurrency"
}
}
}
}Format options: , , , , etc.
compactcurrencysimpleCurrencydecimalPattern自动格式化数字:
json
{
"price": "Price: {value}",
"@price": {
"placeholders": {
"value": {
"type": "int",
"format": "simpleCurrency"
}
}
}
}格式化选项包括:、、、等。
compactcurrencysimpleCurrencydecimalPatternDates
日期
Format dates automatically:
json
{
"eventDate": "Event on {date}",
"@eventDate": {
"placeholders": {
"date": {
"type": "DateTime",
"format": "yMMMd"
}
}
}
}Format options: , , , , etc.
yMdyMMMdyMMMMdHmFor complete formatting options, see number-date-formats.md.
自动格式化日期:
json
{
"eventDate": "Event on {date}",
"@eventDate": {
"placeholders": {
"date": {
"type": "DateTime",
"format": "yMMMd"
}
}
}
}格式化选项包括:、、、等。
yMdyMMMdyMMMMdHm如需完整的格式化选项,请查看number-date-formats.md。
Advanced Topics
高级主题
Locale Override
Locale覆盖
Override locale for specific widgets:
dart
Localizations.override(
context: context,
locale: const Locale('es'),
child: CalendarDatePicker(...),
)为特定组件覆盖Locale:
dart
Localizations.override(
context: context,
locale: const Locale('es'),
child: CalendarDatePicker(...),
)Custom Locale Definitions
自定义Locale定义
For complex locales (Chinese, French regions):
dart
supportedLocales: [
Locale.fromSubtags(languageCode: 'zh'),
Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans'),
Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'TW'),
]针对复杂Locale(如中文、法语地区):
dart
supportedLocales: [
Locale.fromSubtags(languageCode: 'zh'),
Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans'),
Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'TW'),
]Locale Resolution Callback
Locale解析回调
Control locale fallback:
dart
MaterialApp(
localeResolutionCallback: (locale, supportedLocales) {
// Always accept user's locale
return locale;
},
)控制Locale回退逻辑:
dart
MaterialApp(
localeResolutionCallback: (locale, supportedLocales) {
// 始终接受用户的Locale
return locale;
},
)Access Current Locale
获取当前Locale
Get current app locale:
dart
Locale myLocale = Localizations.localeOf(context);获取应用当前使用的Locale:
dart
Locale myLocale = Localizations.localeOf(context);Setup intl Package
intl包设置
Manual Setup
手动设置
- Add dependencies (same as gen-l10n)
- Create localization class:
dart
class DemoLocalizations {
DemoLocalizations(this.localeName);
static Future<DemoLocalizations> load(Locale locale) {
final String name = Intl.canonicalizedLocale(locale.toString());
return initializeMessages(name).then((_) => DemoLocalizations(name));
}
static DemoLocalizations of(BuildContext context) {
return Localizations.of<DemoLocalizations>(context, DemoLocalizations)!;
}
String get title {
return Intl.message(
'Hello World',
name: 'title',
desc: 'Title',
locale: localeName,
);
}
}- Create delegate:
dart
class DemoLocalizationsDelegate extends LocalizationsDelegate<DemoLocalizations> {
const DemoLocalizationsDelegate();
bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode);
Future<DemoLocalizations> load(Locale locale) => DemoLocalizations.load(locale);
bool shouldReload(DemoLocalizationsDelegate old) => false;
}- Generate ARB files:
bash
dart run intl_translation:extract_to_arb --output-dir=lib/l10n lib/main.dart
dart run intl_translation:generate_from_arb --output-dir=lib/l10n lib/main.dart lib/l10n/intl_*.arb- 添加依赖(与gen-l10n相同)
- 创建本地化类:
dart
class DemoLocalizations {
DemoLocalizations(this.localeName);
static Future<DemoLocalizations> load(Locale locale) {
final String name = Intl.canonicalizedLocale(locale.toString());
return initializeMessages(name).then((_) => DemoLocalizations(name));
}
static DemoLocalizations of(BuildContext context) {
return Localizations.of<DemoLocalizations>(context, DemoLocalizations)!;
}
String get title {
return Intl.message(
'Hello World',
name: 'title',
desc: 'Title',
locale: localeName,
);
}
}- 创建代理类:
dart
class DemoLocalizationsDelegate extends LocalizationsDelegate<DemoLocalizations> {
const DemoLocalizationsDelegate();
bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode);
Future<DemoLocalizations> load(Locale locale) => DemoLocalizations.load(locale);
bool shouldReload(DemoLocalizationsDelegate old) => false;
}- 生成ARB文件:
bash
dart run intl_translation:extract_to_arb --output-dir=lib/l10n lib/main.dart
dart run intl_translation:generate_from_arb --output-dir=lib/l10n lib/main.dart lib/l10n/intl_*.arbCustom Localizations
自定义本地化
For maximum simplicity:
dart
class DemoLocalizations {
DemoLocalizations(this.locale);
final Locale locale;
static DemoLocalizations of(BuildContext context) {
return Localizations.of<DemoLocalizations>(context, DemoLocalizations)!;
}
static const _localizedValues = <String, Map<String, String>>{
'en': {'title': 'Hello World'},
'es': {'title': 'Hola Mundo'},
};
String get title {
return _localizedValues[locale.languageCode]!['title']!;
}
}适用于极简场景:
dart
class DemoLocalizations {
DemoLocalizations(this.locale);
final Locale locale;
static DemoLocalizations of(BuildContext context) {
return Localizations.of<DemoLocalizations>(context, DemoLocalizations)!;
}
static const _localizedValues = <String, Map<String, String>>{
'en': {'title': 'Hello World'},
'es': {'title': 'Hola Mundo'},
};
String get title {
return _localizedValues[locale.languageCode]!['title']!;
}
}Best Practices
最佳实践
- Use gen-l10n for new projects - simpler, safer, better tooling
- Add descriptions to ARB entries - provides context for translators
- Format numbers/dates with format types - automatic locale handling
- Test all locales - verify formatting, RTL, and translations
- Use pluralization - handle count variations correctly
- Keep messages short - easier to translate, more consistent
- Don't concatenate strings - use placeholders instead
- Enable nullable-getter to reduce null checks in user code
- 新项目使用gen-l10n - 更简单、安全,工具支持更完善
- 为ARB条目添加描述 - 为翻译人员提供上下文信息
- 使用格式类型格式化数字/日期 - 自动适配Locale
- 测试所有Locale - 验证格式、RTL(从右到左)布局和翻译内容
- 使用复数处理 - 正确处理数量变化
- 保持消息简短 - 更易翻译,一致性更强
- 不要拼接字符串 - 改用占位符
- 启用可空getter - 减少用户代码中的空检查
Resources
资源
references/
references/
l10n-config.md - Complete reference for configuration options, including output directories, code generation settings, and locale handling.
l10n.yamlarb-format.md - Comprehensive guide to ARB file format, covering simple messages, placeholders, plurals, selects, and metadata.
number-date-formats.md - Number and date formatting reference with format types, patterns, and locale-specific examples.
l10n-config.md - 配置选项的完整参考,包括输出目录、代码生成设置和Locale处理。
l10n.yamlarb-format.md - ARB文件格式的全面指南,涵盖简单消息、占位符、复数、选择器和元数据。
number-date-formats.md - 数字和日期格式化参考,包含格式类型、模式和Locale特定示例。
assets/
assets/
Example templates and boilerplate code can be added here for common internationalization patterns.
此处可添加常见国际化模式的示例模板和样板代码。
When to Use This Skill
适用场景
Use this skill when:
- Adding localization support to a new Flutter app
- Translating existing Flutter app to multiple languages
- Configuring number/date formatting for different locales
- Setting up RTL (right-to-left) language support
- Implementing locale-specific layouts or widgets
- Managing ARB files and translations
- Troubleshooting localization issues
- Adding custom language support beyond built-in locales
- Optimizing app bundle size with deferred loading
在以下场景中使用本指南:
- 为新Flutter应用添加本地化支持
- 将现有Flutter应用翻译为多语言
- 为不同Locale配置数字/日期格式化
- 设置RTL(从右到左)语言支持
- 实现Locale特定的布局或组件
- 管理ARB文件和翻译内容
- 排查本地化问题
- 添加内置Locale之外的自定义语言支持
- 通过延迟加载优化应用包大小