flutter-localizing-apps

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Localizing Flutter Applications

Flutter应用国际化

Contents

目录

Core Configuration

核心配置

Configure the project to support code generation for localizations.
  1. 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
  1. Create an
    l10n.yaml
    file in the project root to configure the
    gen-l10n
    tool:
yaml
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
配置项目以支持本地化代码生成。
  1. pubspec.yaml
    中添加必要的依赖项:
yaml
dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: any

flutter:
  generate: true # Required for l10n code generation
  1. 在项目根目录创建
    l10n.yaml
    文件,配置
    gen-l10n
    工具:
yaml
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart

Optional: Set to false to generate files into lib/ instead of the synthetic package

可选:设置为false可将文件生成到lib/目录而非合成包

synthetic-package: false

synthetic-package: false

undefined
undefined

Defining ARB Resources

定义ARB资源

Store localized strings in Application Resource Bundle (
.arb
) files within the configured
arb-dir
.
Create the template file (e.g.,
lib/l10n/app_en.arb
):
json
{
  "helloWorld": "Hello World!",
  "@helloWorld": {
    "description": "The conventional newborn programmer greeting"
  }
}
Create translation files (e.g.,
lib/l10n/app_es.arb
):
json
{
  "helloWorld": "¡Hola Mundo!"
}
将本地化字符串存储在配置的
arb-dir
目录下的应用资源包(
.arb
)文件中。
创建模板文件(例如
lib/l10n/app_en.arb
):
json
{
  "helloWorld": "Hello World!",
  "@helloWorld": {
    "description": "The conventional newborn programmer greeting"
  }
}
创建翻译文件(例如
lib/l10n/app_es.arb
):
json
{
  "helloWorld": "¡Hola Mundo!"
}

App Integration

应用集成

Initialize the
Localizations
widget by configuring the root
MaterialApp
or
CupertinoApp
.
dart
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
AppLocalizations
class:
dart
Text(AppLocalizations.of(context)!.helloWorld)
Note: If using
WidgetsApp
instead of
MaterialApp
, omit
GlobalMaterialLocalizations.delegate
.
通过配置根
MaterialApp
CupertinoApp
初始化
Localizations
组件。
dart
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(),
);
在组件树中使用生成的
AppLocalizations
类访问本地化值:
dart
Text(AppLocalizations.of(context)!.helloWorld)
注意:如果使用
WidgetsApp
而非
MaterialApp
,请省略
GlobalMaterialLocalizations.delegate

Advanced Formatting

高级格式化

Use placeholders, plurals, and selects for dynamic content. Define parameters in the
@key
metadata.
使用占位符、复数形式和选择器处理动态内容。在
@key
元数据中定义参数。

Placeholders

占位符

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
format
and
optionalParameters
to leverage
intl
formatting.
json
"dateMessage": "Date: {date}",
"@dateMessage": {
  "placeholders": {
    "date": {
      "type": "DateTime",
      "format": "yMd"
    }
  }
}
使用
format
optionalParameters
来利用
intl
的格式化功能。
json
"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
    .arb
    file in the
    arb-dir
    (e.g.,
    app_fr.arb
    ).
  • Translate all keys present in the template
    .arb
    file.
  • Add the new
    Locale
    to the
    supportedLocales
    list in
    MaterialApp
    .
  • Run validator -> Execute
    flutter gen-l10n
    to verify ARB syntax and regenerate
    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
  • 运行验证器 -> 执行
    flutter gen-l10n
    以验证ARB语法并重新生成
    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
    ios/Runner.xcodeproj
    in Xcode.
  • Select the
    Runner
    project in the Project Navigator.
  • Navigate to the
    Info
    tab.
  • Under the Localizations section, click the
    +
    button.
  • Add the newly supported languages/regions.
  • Run validator -> Build the iOS app to ensure
    project.pbxproj
    is correctly updated.
Flutter会处理运行时本地化,但iOS需要在包级别进行配置,以适配App Store和系统设置。
  • 在Xcode中打开
    ios/Runner.xcodeproj
  • 在项目导航器中选择
    Runner
    项目。
  • 切换到“Info”标签页。
  • Localizations部分,点击
    +
    按钮。
  • 添加新支持的语言/区域。
  • 运行验证器 -> 构建iOS应用以确保
    project.pbxproj
    已正确更新。

Troubleshooting & Gotchas

问题排查与注意事项

Missing Localizations Ancestor

缺少本地化祖先组件

Widgets like
TextField
and
CupertinoTabBar
require a
Localizations
ancestor with specific delegates (
MaterialLocalizations
or
CupertinoLocalizations
).
Error:
No MaterialLocalizations found.
or
CupertinoTabBar requires a Localizations parent...
Fix: Ensure the widget is a descendant of
MaterialApp
/
CupertinoApp
. If building a standalone widget tree (e.g., in tests or a custom
WidgetsApp
), wrap the widget in a
Localizations
widget:
dart
Localizations(
  locale: const Locale('en', 'US'),
  delegates: const [
    DefaultWidgetsLocalizations.delegate,
    DefaultMaterialLocalizations.delegate, // Required for TextField
    DefaultCupertinoLocalizations.delegate, // Required for CupertinoTabBar
  ],
  child: child,
)
TextField
CupertinoTabBar
等组件需要带有特定委托(
MaterialLocalizations
CupertinoLocalizations
)的
Localizations
祖先组件。
错误提示:
No MaterialLocalizations found.
CupertinoTabBar requires a Localizations parent...
修复方案: 确保组件是
MaterialApp
/
CupertinoApp
的后代。如果构建独立的组件树(例如在测试或自定义
WidgetsApp
中),请将组件包裹在
Localizations
组件中:
dart
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
Locale.fromSubtags
to explicitly define the
scriptCode
and
countryCode
to prevent Flutter from resolving to an unexpected variant.
dart
supportedLocales: const [
  Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN'),
  Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'TW'),
]
如果支持具有多种脚本的语言(例如中文),请使用
Locale.fromSubtags
显式定义
scriptCode
countryCode
,以避免Flutter解析为意外的变体。
dart
supportedLocales: const [
  Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN'),
  Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'TW'),
]