flutter-localization

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Flutter Localization Setup

Flutter 国际化配置

Goal

目标

Configures and implements internationalization (i18n) and localization (l10n) in a Flutter application. This skill manages dependency injection (
flutter_localizations
,
intl
), code generation configuration (
l10n.yaml
), root widget setup (
MaterialApp
,
CupertinoApp
, or
WidgetsApp
),
.arb
translation file management, and platform-specific configurations (iOS Xcode project updates). It ensures proper locale resolution and prevents common assertion errors related to missing localization delegates in specific widgets like
TextField
and
CupertinoTabBar
.
在Flutter应用中配置并实现国际化(i18n)和本地化(l10n)。本指南涵盖依赖引入(
flutter_localizations
intl
)、代码生成配置(
l10n.yaml
)、根组件设置(
MaterialApp
CupertinoApp
WidgetsApp
)、
.arb
翻译文件管理,以及平台特定配置(iOS Xcode项目更新)。它可以确保正确的语言区域解析,避免
TextField
CupertinoTabBar
等特定组件因缺少本地化代理而出现的常见断言错误。

Decision Logic

决策逻辑

  1. Determine App Root: Identify if the application uses
    MaterialApp
    ,
    CupertinoApp
    , or
    WidgetsApp
    to inject the correct global delegates.
  2. Identify Target Platforms: If iOS is a target platform, Xcode project files (
    Info.plist
    /
    project.pbxproj
    ) must be updated to expose supported locales to the App Store.
  3. Analyze Widget Tree: Check for isolated
    TextField
    or
    CupertinoTabBar
    widgets that might exist outside the root app's localization scope. If found, wrap them in explicit
    Localizations
    widgets.
  4. Determine Locale Complexity: If supporting languages with multiple scripts/regions (e.g., Chinese
    zh_Hans_CN
    ), use
    Locale.fromSubtags
    instead of the default
    Locale
    constructor.
  1. 确定应用根组件: 识别应用使用的是
    MaterialApp
    CupertinoApp
    还是
    WidgetsApp
    ,以便注入正确的全局代理。
  2. 确定目标平台: 如果目标平台包含iOS,必须更新Xcode项目文件(
    Info.plist
    /
    project.pbxproj
    ),以便向App Store公开支持的语言区域。
  3. 分析组件树: 检查是否存在位于根应用本地化作用域之外的独立
    TextField
    CupertinoTabBar
    组件。如果存在,使用显式的
    Localizations
    组件包裹它们。
  4. 确定语言区域复杂度: 如果支持包含多文字/多地区的语言(例如中文
    zh_Hans_CN
    ),请使用
    Locale.fromSubtags
    而非默认的
    Locale
    构造函数。

Instructions

操作指南

  1. Configure Dependencies Update
    pubspec.yaml
    to include required packages and enable code generation.
    yaml
    dependencies:
      flutter:
        sdk: flutter
      flutter_localizations:
        sdk: flutter
      intl: any
    
    flutter:
      generate: true
  2. Configure Code Generation Create an
    l10n.yaml
    file in the project root to define the localization tool's behavior.
    yaml
    arb-dir: lib/l10n
    template-arb-file: app_en.arb
    output-localization-file: app_localizations.dart
    synthetic-package: false
  3. Define Supported Locales STOP AND ASK THE USER: "Which languages and regions do you want to support? Please provide a list of language codes (e.g., 'en', 'es', 'zh_Hans_CN')."
  4. Create ARB Files Generate the template
    .arb
    file (e.g.,
    lib/l10n/app_en.arb
    ) and corresponding translation files. Implement placeholders, plurals, and selects as needed.
    json
    {
      "helloWorld": "Hello World!",
      "@helloWorld": {
        "description": "Standard greeting"
      },
      "greeting": "Hello {userName}",
      "@greeting": {
        "description": "Greeting with a parameter",
        "placeholders": {
          "userName": {
            "type": "String"
          }
        }
      },
      "nWombats": "{count, plural, =0{no wombats} =1{1 wombat} other{{count} wombats}}",
      "@nWombats": {
        "placeholders": {
          "count": {
            "type": "num",
            "format": "compact"
          }
        }
      }
    }
  5. Initialize Root App Import the generated localizations file and configure the root
    MaterialApp
    or
    CupertinoApp
    .
    dart
    import 'package:flutter_localizations/flutter_localizations.dart';
    import 'package:your_app_name/l10n/app_localizations.dart'; // Adjust path based on synthetic-package setting
    
    // Inside your root widget build method:
    return MaterialApp(
      title: 'Localized App',
      localizationsDelegates: const [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: const [
        Locale('en', ''), // English
        Locale('es', ''), // Spanish
        Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN'),
      ],
      home: const MyHomePage(),
    );
  6. Handle Isolated Widgets (If Applicable) If a
    TextField
    or
    CupertinoTabBar
    throws a missing
    MaterialLocalizations
    or
    Localizations
    ancestor error, inject a
    Localizations
    widget directly above it.
    dart
    Localizations(
      locale: const Locale('en', 'US'),
      delegates: const <LocalizationsDelegate<dynamic>>[
        DefaultWidgetsLocalizations.delegate,
        DefaultMaterialLocalizations.delegate,
        DefaultCupertinoLocalizations.delegate,
      ],
      child: CupertinoTabBar(
        items: const <BottomNavigationBarItem>[...],
      ),
    )
  7. Configure iOS Project STOP AND ASK THE USER: "Does this project target iOS? If yes, I will provide instructions for updating the Xcode project." If yes, instruct the user to:
    1. Open
      ios/Runner.xcodeproj
      in Xcode.
    2. Select the
      Runner
      project in the Project Navigator.
    3. Go to the
      Info
      tab.
    4. Under Localizations, click
      +
      to add all supported languages.
  8. Validate and Fix Run
    flutter gen-l10n
    . Verify that
    app_localizations.dart
    is generated successfully. If compilation fails with "No MaterialLocalizations found" or "CupertinoTabBar requires a Localizations parent", traverse up the widget tree from the failing widget and ensure
    localizationsDelegates
    are properly provided.
  1. 配置依赖 更新
    pubspec.yaml
    以引入所需的包并启用代码生成。
    yaml
    dependencies:
      flutter:
        sdk: flutter
      flutter_localizations:
        sdk: flutter
      intl: any
    
    flutter:
      generate: true
  2. 配置代码生成 在项目根目录创建
    l10n.yaml
    文件,定义本地化工具的运行规则。
    yaml
    arb-dir: lib/l10n
    template-arb-file: app_en.arb
    output-localization-file: app_localizations.dart
    synthetic-package: false
  3. 定义支持的语言区域 请暂停并询问用户: "你希望支持哪些语言和地区?请提供语言代码列表(例如'en'、'es'、'zh_Hans_CN')。"
  4. 创建ARB文件 生成模板
    .arb
    文件(例如
    lib/l10n/app_en.arb
    )和对应的翻译文件,根据需要实现占位符、复数和选择逻辑。
    json
    {
      "helloWorld": "Hello World!",
      "@helloWorld": {
        "description": "Standard greeting"
      },
      "greeting": "Hello {userName}",
      "@greeting": {
        "description": "Greeting with a parameter",
        "placeholders": {
          "userName": {
            "type": "String"
          }
        }
      },
      "nWombats": "{count, plural, =0{no wombats} =1{1 wombat} other{{count} wombats}}",
      "@nWombats": {
        "placeholders": {
          "count": {
            "type": "num",
            "format": "compact"
          }
        }
      }
    }
  5. 初始化根应用 引入生成的本地化文件,配置根
    MaterialApp
    CupertinoApp
    dart
    import 'package:flutter_localizations/flutter_localizations.dart';
    import 'package:your_app_name/l10n/app_localizations.dart'; // 根据synthetic-package配置调整路径
    
    // 在根组件的build方法内:
    return MaterialApp(
      title: 'Localized App',
      localizationsDelegates: const [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: const [
        Locale('en', ''), // English
        Locale('es', ''), // Spanish
        Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN'),
      ],
      home: const MyHomePage(),
    );
  6. 处理独立组件(如有需要) 如果
    TextField
    CupertinoTabBar
    抛出缺少
    MaterialLocalizations
    Localizations
    父组件的错误,请在其上层直接插入
    Localizations
    组件。
    dart
    Localizations(
      locale: const Locale('en', 'US'),
      delegates: const <LocalizationsDelegate<dynamic>>[
        DefaultWidgetsLocalizations.delegate,
        DefaultMaterialLocalizations.delegate,
        DefaultCupertinoLocalizations.delegate,
      ],
      child: CupertinoTabBar(
        items: const <BottomNavigationBarItem>[...],
      ),
    )
  7. 配置iOS项目 请暂停并询问用户: "这个项目的目标平台包含iOS吗?如果包含,我将提供更新Xcode项目的指引。" 如果答案为是,指导用户执行以下操作:
    1. 在Xcode中打开
      ios/Runner.xcodeproj
    2. 在项目导航栏中选择
      Runner
      项目。
    3. 进入
      Info
      标签页。
    4. 本地化区域,点击
      +
      添加所有支持的语言。
  8. 验证与修复 运行
    flutter gen-l10n
    ,确认
    app_localizations.dart
    已成功生成。如果编译报错提示"No MaterialLocalizations found"或"CupertinoTabBar requires a Localizations parent",请从报错组件向上遍历组件树,确保
    localizationsDelegates
    已正确配置。

Constraints

约束条件

  • No Synthetic Packages: Ensure
    synthetic-package: false
    is considered if the user's environment requires direct source generation, or rely on standard
    generate: true
    behavior for modern Flutter versions. Do not use
    package:flutter_gen
    imports if
    synthetic-package: false
    is set.
  • Widget Requirements:
    TextField
    MUST have a
    MaterialLocalizations
    ancestor.
    CupertinoTabBar
    MUST have a
    Localizations
    ancestor.
  • Complex Locales: Always use
    Locale.fromSubtags
    for languages requiring script codes (e.g., Chinese
    zh_Hans
    ,
    zh_Hant
    ).
  • ARB Syntax: Ensure all placeholders used in
    .arb
    strings are explicitly defined in the corresponding
    @
    metadata object.
  • Escaping: If literal curly braces
    {}
    or single quotes
    '
    are needed in
    .arb
    files, enable
    use-escaping: true
    in
    l10n.yaml
    and use consecutive single quotes
    ''
    for escaping.
  • 不使用合成包: 如果用户环境要求直接生成源代码,请确保配置
    synthetic-package: false
    ;高版本Flutter可以直接使用标准的
    generate: true
    配置。如果设置了
    synthetic-package: false
    ,请勿使用
    package:flutter_gen
    引入文件。
  • 组件要求:
    TextField
    必须有
    MaterialLocalizations
    父组件,
    CupertinoTabBar
    必须有
    Localizations
    父组件。
  • 复杂语言区域: 对于需要文字代码的语言(例如中文
    zh_Hans
    zh_Hant
    ),必须使用
    Locale.fromSubtags
  • ARB语法: 确保
    .arb
    字符串中使用的所有占位符都在对应的
    @
    元数据对象中明确定义。
  • 转义规则: 如果
    .arb
    文件中需要使用字面量大括号
    {}
    或单引号
    '
    ,请在
    l10n.yaml
    中启用
    use-escaping: true
    ,并使用连续两个单引号
    ''
    进行转义。