flutter-localizing-apps
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseLocalizing Flutter Applications
Flutter应用国际化
Contents
目录
Core Configuration
核心配置
Configure the project to support code generation for localizations.
- Add required dependencies to :
pubspec.yaml
yaml
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: any
flutter:
generate: true # Required for l10n code generation- Create an file in the project root to configure the
l10n.yamltool:gen-l10n
yaml
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart配置项目以支持本地化代码生成。
- 向中添加必要的依赖项:
pubspec.yaml
yaml
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: any
flutter:
generate: true # Required for l10n code generation- 在项目根目录创建文件,配置
l10n.yaml工具:gen-l10n
yaml
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dartOptional: Set to false to generate files into lib/ instead of the synthetic package
可选:设置为false可将文件生成到lib/目录而非合成包
synthetic-package: false
synthetic-package: false
undefinedundefinedDefining ARB Resources
定义ARB资源
Store localized strings in Application Resource Bundle () files within the configured .
.arbarb-dirCreate the template file (e.g., ):
lib/l10n/app_en.arbjson
{
"helloWorld": "Hello World!",
"@helloWorld": {
"description": "The conventional newborn programmer greeting"
}
}Create translation files (e.g., ):
lib/l10n/app_es.arbjson
{
"helloWorld": "¡Hola Mundo!"
}将本地化字符串存储在配置的目录下的应用资源包()文件中。
arb-dir.arb创建模板文件(例如):
lib/l10n/app_en.arbjson
{
"helloWorld": "Hello World!",
"@helloWorld": {
"description": "The conventional newborn programmer greeting"
}
}创建翻译文件(例如):
lib/l10n/app_es.arbjson
{
"helloWorld": "¡Hola Mundo!"
}App Integration
应用集成
Initialize the widget by configuring the root or .
LocalizationsMaterialAppCupertinoAppdart
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; // Adjust import if synthetic-package is false
return MaterialApp(
title: 'Localized App',
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('en'), // English
Locale('es'), // Spanish
],
home: const MyHomePage(),
);Access localized values in the widget tree using the generated class:
AppLocalizationsdart
Text(AppLocalizations.of(context)!.helloWorld)Note: If using instead of , omit .
WidgetsAppMaterialAppGlobalMaterialLocalizations.delegate通过配置根或初始化组件。
MaterialAppCupertinoAppLocalizationsdart
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; // 若synthetic-package设为false,请调整导入路径
return MaterialApp(
title: 'Localized App',
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('en'), // English
Locale('es'), // Spanish
],
home: const MyHomePage(),
);在组件树中使用生成的类访问本地化值:
AppLocalizationsdart
Text(AppLocalizations.of(context)!.helloWorld)注意:如果使用而非,请省略。
WidgetsAppMaterialAppGlobalMaterialLocalizations.delegateAdvanced Formatting
高级格式化
Use placeholders, plurals, and selects for dynamic content. Define parameters in the metadata.
@key使用占位符、复数形式和选择器处理动态内容。在元数据中定义参数。
@keyPlaceholders
占位符
json
"hello": "Hello {userName}",
"@hello": {
"description": "A message with a single parameter",
"placeholders": {
"userName": {
"type": "String",
"example": "Bob"
}
}
}json
"hello": "Hello {userName}",
"@hello": {
"description": "A message with a single parameter",
"placeholders": {
"userName": {
"type": "String",
"example": "Bob"
}
}
}Plurals
复数形式
json
"nWombats": "{count, plural, =0{no wombats} =1{1 wombat} other{{count} wombats}}",
"@nWombats": {
"placeholders": {
"count": {
"type": "num",
"format": "compact"
}
}
}json
"nWombats": "{count, plural, =0{no wombats} =1{1 wombat} other{{count} wombats}}",
"@nWombats": {
"placeholders": {
"count": {
"type": "num",
"format": "compact"
}
}
}Selects (Gender/Enums)
选择器(性别/枚举)
json
"pronoun": "{gender, select, male{he} female{she} other{they}}",
"@pronoun": {
"placeholders": {
"gender": {
"type": "String"
}
}
}json
"pronoun": "{gender, select, male{he} female{she} other{they}}",
"@pronoun": {
"placeholders": {
"gender": {
"type": "String"
}
}
}Dates and Numbers
日期与数字
Use and to leverage formatting.
formatoptionalParametersintljson
"dateMessage": "Date: {date}",
"@dateMessage": {
"placeholders": {
"date": {
"type": "DateTime",
"format": "yMd"
}
}
}使用和来利用的格式化功能。
formatoptionalParametersintljson
"dateMessage": "Date: {date}",
"@dateMessage": {
"placeholders": {
"date": {
"type": "DateTime",
"format": "yMd"
}
}
}Workflows
工作流
Task Progress: Adding a New Language
任务进度:添加新语言
Copy this checklist to track progress when introducing a new locale.
- Create a new file in the
.arb(e.g.,arb-dir).app_fr.arb - Translate all keys present in the template file.
.arb - Add the new to the
Localelist insupportedLocales.MaterialApp - Run validator -> Execute to verify ARB syntax and regenerate
flutter gen-l10n.AppLocalizations - Review errors -> Fix any missing placeholders or malformed plural/select statements.
- If targeting iOS, complete the "Configuring iOS App Bundle" workflow.
复制此清单以跟踪引入新区域设置的进度。
- 在目录中创建新的
arb-dir文件(例如.arb)。app_fr.arb - 翻译模板文件中的所有键值。
.arb - 在的
MaterialApp列表中添加新的supportedLocales。Locale - 运行验证器 -> 执行以验证ARB语法并重新生成
flutter gen-l10n。AppLocalizations - 检查错误 -> 修复任何缺失的占位符或格式错误的复数/选择器语句。
- 若针对iOS平台,完成“配置iOS应用包”工作流。
Task Progress: Configuring iOS App Bundle
任务进度:配置iOS应用包
Flutter handles runtime localization, but iOS requires bundle-level configuration for the App Store and system settings.
- Open in Xcode.
ios/Runner.xcodeproj - Select the project in the Project Navigator.
Runner - Navigate to the tab.
Info - Under the Localizations section, click the button.
+ - Add the newly supported languages/regions.
- Run validator -> Build the iOS app to ensure is correctly updated.
project.pbxproj
Flutter会处理运行时本地化,但iOS需要在包级别进行配置,以适配App Store和系统设置。
- 在Xcode中打开。
ios/Runner.xcodeproj - 在项目导航器中选择项目。
Runner - 切换到“Info”标签页。
- 在Localizations部分,点击按钮。
+ - 添加新支持的语言/区域。
- 运行验证器 -> 构建iOS应用以确保已正确更新。
project.pbxproj
Troubleshooting & Gotchas
问题排查与注意事项
Missing Localizations Ancestor
缺少本地化祖先组件
Widgets like and require a ancestor with specific delegates ( or ).
TextFieldCupertinoTabBarLocalizationsMaterialLocalizationsCupertinoLocalizationsError: or
Fix: Ensure the widget is a descendant of /. If building a standalone widget tree (e.g., in tests or a custom ), wrap the widget in a widget:
No MaterialLocalizations found.CupertinoTabBar requires a Localizations parent...MaterialAppCupertinoAppWidgetsAppLocalizationsdart
Localizations(
locale: const Locale('en', 'US'),
delegates: const [
DefaultWidgetsLocalizations.delegate,
DefaultMaterialLocalizations.delegate, // Required for TextField
DefaultCupertinoLocalizations.delegate, // Required for CupertinoTabBar
],
child: child,
)TextFieldCupertinoTabBarMaterialLocalizationsCupertinoLocalizationsLocalizations错误提示: 或
修复方案: 确保组件是/的后代。如果构建独立的组件树(例如在测试或自定义中),请将组件包裹在组件中:
No MaterialLocalizations found.CupertinoTabBar requires a Localizations parent...MaterialAppCupertinoAppWidgetsAppLocalizationsdart
Localizations(
locale: const Locale('en', 'US'),
delegates: const [
DefaultWidgetsLocalizations.delegate,
DefaultMaterialLocalizations.delegate, // Required for TextField
DefaultCupertinoLocalizations.delegate, // Required for CupertinoTabBar
],
child: child,
)Advanced Locale Definition
高级区域设置定义
If supporting languages with multiple scripts (e.g., Chinese), use to explicitly define the and to prevent Flutter from resolving to an unexpected variant.
Locale.fromSubtagsscriptCodecountryCodedart
supportedLocales: const [
Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN'),
Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'TW'),
]如果支持具有多种脚本的语言(例如中文),请使用显式定义和,以避免Flutter解析为意外的变体。
Locale.fromSubtagsscriptCodecountryCodedart
supportedLocales: const [
Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN'),
Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'TW'),
]