Flutter 小白入门教程Flutter 小白入门教程
首页
学习指南
项目实战
Flutter 官网
编程指南
首页
学习指南
项目实战
Flutter 官网
编程指南
  • 入门基础

    • 📚 基础教程
    • 第1章 - 认识 Flutter
    • 第2章 - 环境搭建
    • 第3章 - Dart 语言基础
    • 第4章 - 第一个 Flutter 应用
    • 第5章 - Widget 基础
    • 第6章 - 布局系统
    • 第7章 - 状态管理入门
    • 第8章 - 页面导航
    • 第9章 - 资源管理
  • 进阶开发

    • 第10章 - 网络请求
    • 第11章 - 本地存储
    • 第12章 - 对话框与反馈
    • 第13章 - 列表进阶
    • 第14章 - 主题定制
    • 第15章 - 状态管理进阶
    • 第16章 - 动画入门
    • 第17章 - 常用第三方包
  • 调试与发布

    • 第18章 - 调试与性能优化
    • 第19章 - 打包与发布
  • 附录

    • 附录A - UI 框架与组件库推荐
    • 附录B - 项目结构最佳实践
    • 附录C - 国际化配置
    • 附录D - 权限处理

附录C - 国际化配置

嗨,朋友!我是长安。

如果你的 App 需要支持多种语言,国际化(i18n)就是必不可少的功能。Flutter 提供了完善的国际化支持,让你的 App 轻松走向全球!

这一章,我会教你如何配置多语言支持,从简单方案到专业方案都会涉及!

🌍 国际化基础概念

什么是国际化?

  • 国际化(i18n):让应用支持多种语言的能力
  • 本地化(l10n):将应用翻译成特定语言的过程

Flutter 国际化方案

方案复杂度适用场景
手动管理⭐语言少、文本少
flutter_localizations⭐⭐官方方案,推荐
intl 包⭐⭐⭐专业级,大型项目
easy_localization⭐⭐第三方,简单易用
get(GetX)⭐⭐已用 GetX 的项目

📦 方案一:flutter_localizations(官方推荐)

1. 添加依赖

# pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:  # 添加这个
    sdk: flutter
  intl: ^0.19.0  # 国际化工具

2. 配置 MaterialApp

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My App',
      
      // 支持的语言列表
      supportedLocales: const [
        Locale('zh', 'CN'),  // 简体中文
        Locale('zh', 'TW'),  // 繁体中文
        Locale('en', 'US'),  // 英文
        Locale('ja', 'JP'),  // 日文
      ],
      
      // 本地化代理
      localizationsDelegates: const [
        GlobalMaterialLocalizations.delegate,  // Material 组件本地化
        GlobalWidgetsLocalizations.delegate,   // Widget 本地化
        GlobalCupertinoLocalizations.delegate, // Cupertino 组件本地化
        // AppLocalizations.delegate,           // 自定义本地化(后面会加)
      ],
      
      // 语言选择逻辑
      localeResolutionCallback: (locale, supportedLocales) {
        // 遍历支持的语言,找到匹配的
        for (var supportedLocale in supportedLocales) {
          if (supportedLocale.languageCode == locale?.languageCode &&
              supportedLocale.countryCode == locale?.countryCode) {
            return supportedLocale;
          }
        }
        // 默认返回第一个(中文)
        return supportedLocales.first;
      },
      
      home: const HomePage(),
    );
  }
}

3. 创建本地化类

// lib/l10n/app_localizations.dart
import 'package:flutter/material.dart';

class AppLocalizations {
  final Locale locale;

  AppLocalizations(this.locale);

  // 获取当前本地化实例
  static AppLocalizations of(BuildContext context) {
    return Localizations.of<AppLocalizations>(context, AppLocalizations)!;
  }

  // 本地化代理
  static const LocalizationsDelegate<AppLocalizations> delegate =
      _AppLocalizationsDelegate();

  // 翻译字典
  static final Map<String, Map<String, String>> _localizedValues = {
    'en': {
      'app_title': 'My App',
      'home': 'Home',
      'settings': 'Settings',
      'profile': 'Profile',
      'login': 'Login',
      'logout': 'Logout',
      'welcome': 'Welcome',
      'hello_user': 'Hello, {name}!',
      'items_count': '{count} items',
    },
    'zh': {
      'app_title': '我的应用',
      'home': '首页',
      'settings': '设置',
      'profile': '个人中心',
      'login': '登录',
      'logout': '退出登录',
      'welcome': '欢迎',
      'hello_user': '你好,{name}!',
      'items_count': '{count} 个项目',
    },
    'ja': {
      'app_title': 'マイアプリ',
      'home': 'ホーム',
      'settings': '設定',
      'profile': 'プロフィール',
      'login': 'ログイン',
      'logout': 'ログアウト',
      'welcome': 'ようこそ',
      'hello_user': 'こんにちは、{name}さん!',
      'items_count': '{count} アイテム',
    },
  };

  // 获取翻译文本
  String _translate(String key) {
    return _localizedValues[locale.languageCode]?[key] ?? key;
  }

  // 常用文本 getter
  String get appTitle => _translate('app_title');
  String get home => _translate('home');
  String get settings => _translate('settings');
  String get profile => _translate('profile');
  String get login => _translate('login');
  String get logout => _translate('logout');
  String get welcome => _translate('welcome');

  // 带参数的翻译
  String helloUser(String name) {
    return _translate('hello_user').replaceAll('{name}', name);
  }

  String itemsCount(int count) {
    return _translate('items_count').replaceAll('{count}', count.toString());
  }
}

// 本地化代理
class _AppLocalizationsDelegate
    extends LocalizationsDelegate<AppLocalizations> {
  const _AppLocalizationsDelegate();

  @override
  bool isSupported(Locale locale) {
    return ['en', 'zh', 'ja'].contains(locale.languageCode);
  }

  @override
  Future<AppLocalizations> load(Locale locale) async {
    return AppLocalizations(locale);
  }

  @override
  bool shouldReload(_AppLocalizationsDelegate old) => false;
}

4. 注册并使用

// lib/main.dart
import 'l10n/app_localizations.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: const [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        AppLocalizations.delegate,  // 添加自定义代理
      ],
      supportedLocales: const [
        Locale('zh', 'CN'),
        Locale('en', 'US'),
        Locale('ja', 'JP'),
      ],
      home: const HomePage(),
    );
  }
}

// 页面中使用
class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    // 获取本地化实例
    final l10n = AppLocalizations.of(context);

    return Scaffold(
      appBar: AppBar(
        title: Text(l10n.appTitle),
      ),
      body: Column(
        children: [
          Text(l10n.welcome),
          Text(l10n.helloUser('张三')),
          Text(l10n.itemsCount(5)),
        ],
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: [
          BottomNavigationBarItem(
            icon: const Icon(Icons.home),
            label: l10n.home,
          ),
          BottomNavigationBarItem(
            icon: const Icon(Icons.settings),
            label: l10n.settings,
          ),
          BottomNavigationBarItem(
            icon: const Icon(Icons.person),
            label: l10n.profile,
          ),
        ],
      ),
    );
  }
}

📁 方案二:intl 包 + ARB 文件(专业方案)

使用 .arb 文件管理翻译,更适合大型项目。

1. 添加依赖

# pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: ^0.19.0

dev_dependencies:
  intl_utils: ^2.8.5  # 可选,用于生成代码

# 启用代码生成
flutter:
  generate: true

2. 配置 l10n.yaml

# l10n.yaml(项目根目录)
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
output-class: AppLocalizations

3. 创建 ARB 文件

// lib/l10n/app_en.arb
{
  "@@locale": "en",
  "appTitle": "My App",
  "@appTitle": {
    "description": "The title of the application"
  },
  "home": "Home",
  "settings": "Settings",
  "profile": "Profile",
  "login": "Login",
  "logout": "Logout",
  "welcome": "Welcome",
  
  "helloUser": "Hello, {name}!",
  "@helloUser": {
    "description": "Greeting with user name",
    "placeholders": {
      "name": {
        "type": "String",
        "example": "Tom"
      }
    }
  },
  
  "itemsCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}",
  "@itemsCount": {
    "description": "Number of items",
    "placeholders": {
      "count": {
        "type": "int"
      }
    }
  },
  
  "lastLogin": "Last login: {date}",
  "@lastLogin": {
    "description": "Last login time",
    "placeholders": {
      "date": {
        "type": "DateTime",
        "format": "yMMMd"
      }
    }
  }
}
// lib/l10n/app_zh.arb
{
  "@@locale": "zh",
  "appTitle": "我的应用",
  "home": "首页",
  "settings": "设置",
  "profile": "个人中心",
  "login": "登录",
  "logout": "退出登录",
  "welcome": "欢迎",
  "helloUser": "你好,{name}!",
  "itemsCount": "{count, plural, =0{没有项目} =1{1 个项目} other{{count} 个项目}}",
  "lastLogin": "上次登录:{date}"
}
// lib/l10n/app_ja.arb
{
  "@@locale": "ja",
  "appTitle": "マイアプリ",
  "home": "ホーム",
  "settings": "設定",
  "profile": "プロフィール",
  "login": "ログイン",
  "logout": "ログアウト",
  "welcome": "ようこそ",
  "helloUser": "こんにちは、{name}さん!",
  "itemsCount": "{count, plural, =0{アイテムなし} =1{1 アイテム} other{{count} アイテム}}",
  "lastLogin": "最終ログイン:{date}"
}

4. 生成代码

# 运行 Flutter 命令生成本地化代码
flutter gen-l10n

生成的文件会在 .dart_tool/flutter_gen/gen_l10n/ 目录。

5. 使用生成的本地化类

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: AppLocalizations.localizationsDelegates,
      supportedLocales: AppLocalizations.supportedLocales,
      home: const HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    final l10n = AppLocalizations.of(context)!;

    return Scaffold(
      appBar: AppBar(title: Text(l10n.appTitle)),
      body: Column(
        children: [
          Text(l10n.welcome),
          Text(l10n.helloUser('张三')),
          Text(l10n.itemsCount(0)),   // "没有项目"
          Text(l10n.itemsCount(1)),   // "1 个项目"
          Text(l10n.itemsCount(5)),   // "5 个项目"
          Text(l10n.lastLogin(DateTime.now())),
        ],
      ),
    );
  }
}

🚀 方案三:easy_localization(简单易用)

第三方包,配置简单,支持 JSON/YAML 文件。

1. 添加依赖

dependencies:
  easy_localization: ^3.0.5

2. 创建翻译文件

assets/
└── translations/
    ├── en.json
    ├── zh-CN.json
    └── ja.json
// assets/translations/en.json
{
  "app_title": "My App",
  "home": "Home",
  "settings": "Settings",
  "profile": "Profile",
  "login": "Login",
  "logout": "Logout",
  "welcome": "Welcome",
  "hello_user": "Hello, {}!",
  "items_count": {
    "zero": "No items",
    "one": "1 item",
    "other": "{} items"
  },
  "nav": {
    "home": "Home",
    "discover": "Discover",
    "mine": "Mine"
  }
}
// assets/translations/zh-CN.json
{
  "app_title": "我的应用",
  "home": "首页",
  "settings": "设置",
  "profile": "个人中心",
  "login": "登录",
  "logout": "退出登录",
  "welcome": "欢迎",
  "hello_user": "你好,{}!",
  "items_count": {
    "zero": "没有项目",
    "one": "1 个项目",
    "other": "{} 个项目"
  },
  "nav": {
    "home": "首页",
    "discover": "发现",
    "mine": "我的"
  }
}

3. 配置 pubspec.yaml

flutter:
  assets:
    - assets/translations/

4. 初始化并使用

import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await EasyLocalization.ensureInitialized();

  runApp(
    EasyLocalization(
      supportedLocales: const [
        Locale('en'),
        Locale('zh', 'CN'),
        Locale('ja'),
      ],
      path: 'assets/translations',
      fallbackLocale: const Locale('zh', 'CN'),
      child: const MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'app_title'.tr(),  // 使用 .tr() 翻译
      localizationsDelegates: context.localizationDelegates,
      supportedLocales: context.supportedLocales,
      locale: context.locale,
      home: const HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('app_title'.tr()),
      ),
      body: Column(
        children: [
          // 基本翻译
          Text('welcome'.tr()),
          
          // 带参数
          Text('hello_user'.tr(args: ['张三'])),
          
          // 复数形式
          Text('items_count'.plural(0)),   // "没有项目"
          Text('items_count'.plural(1)),   // "1 个项目"
          Text('items_count'.plural(5)),   // "5 个项目"
          
          // 嵌套 key
          Text('nav.home'.tr()),
          
          // 切换语言按钮
          ElevatedButton(
            onPressed: () {
              context.setLocale(const Locale('en'));
            },
            child: const Text('English'),
          ),
          ElevatedButton(
            onPressed: () {
              context.setLocale(const Locale('zh', 'CN'));
            },
            child: const Text('中文'),
          ),
        ],
      ),
    );
  }
}

🎨 方案四:GetX 国际化

如果你已经在使用 GetX,可以直接用它的国际化功能。

1. 创建翻译类

// lib/l10n/translations.dart
import 'package:get/get.dart';

class AppTranslations extends Translations {
  @override
  Map<String, Map<String, String>> get keys => {
    'en_US': {
      'app_title': 'My App',
      'home': 'Home',
      'settings': 'Settings',
      'profile': 'Profile',
      'login': 'Login',
      'logout': 'Logout',
      'welcome': 'Welcome',
      'hello_user': 'Hello, @name!',
      'items_count': '@count items',
    },
    'zh_CN': {
      'app_title': '我的应用',
      'home': '首页',
      'settings': '设置',
      'profile': '个人中心',
      'login': '登录',
      'logout': '退出登录',
      'welcome': '欢迎',
      'hello_user': '你好,@name!',
      'items_count': '@count 个项目',
    },
    'ja_JP': {
      'app_title': 'マイアプリ',
      'home': 'ホーム',
      'settings': '設定',
      'profile': 'プロフィール',
      'login': 'ログイン',
      'logout': 'ログアウト',
      'welcome': 'ようこそ',
      'hello_user': 'こんにちは、@nameさん!',
      'items_count': '@count アイテム',
    },
  };
}

2. 配置 GetMaterialApp

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'l10n/translations.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'app_title'.tr,
      
      // 国际化配置
      translations: AppTranslations(),
      locale: const Locale('zh', 'CN'),  // 默认语言
      fallbackLocale: const Locale('en', 'US'),  // 后备语言
      
      home: const HomePage(),
    );
  }
}

3. 使用翻译

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('app_title'.tr),
      ),
      body: Column(
        children: [
          // 基本翻译
          Text('welcome'.tr),
          
          // 带参数
          Text('hello_user'.trParams({'name': '张三'})),
          
          // 带参数(数字)
          Text('items_count'.trParams({'count': '5'})),
          
          // 切换语言
          ElevatedButton(
            onPressed: () {
              Get.updateLocale(const Locale('en', 'US'));
            },
            child: const Text('English'),
          ),
          ElevatedButton(
            onPressed: () {
              Get.updateLocale(const Locale('zh', 'CN'));
            },
            child: const Text('中文'),
          ),
          ElevatedButton(
            onPressed: () {
              Get.updateLocale(const Locale('ja', 'JP'));
            },
            child: const Text('日本語'),
          ),
          
          // 显示当前语言
          Text('当前语言:${Get.locale}'),
        ],
      ),
    );
  }
}

🔄 动态切换语言

保存语言偏好

import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/material.dart';

class LanguageService {
  static const String _key = 'language_code';

  // 保存语言设置
  static Future<void> saveLanguage(Locale locale) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(_key, '${locale.languageCode}_${locale.countryCode}');
  }

  // 读取语言设置
  static Future<Locale?> getSavedLanguage() async {
    final prefs = await SharedPreferences.getInstance();
    final code = prefs.getString(_key);
    if (code != null) {
      final parts = code.split('_');
      return Locale(parts[0], parts.length > 1 ? parts[1] : null);
    }
    return null;
  }
}

语言选择页面

class LanguageSettingsPage extends StatelessWidget {
  const LanguageSettingsPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('语言设置')),
      body: ListView(
        children: [
          _buildLanguageTile(
            context,
            '简体中文',
            const Locale('zh', 'CN'),
          ),
          _buildLanguageTile(
            context,
            '繁體中文',
            const Locale('zh', 'TW'),
          ),
          _buildLanguageTile(
            context,
            'English',
            const Locale('en', 'US'),
          ),
          _buildLanguageTile(
            context,
            '日本語',
            const Locale('ja', 'JP'),
          ),
          _buildLanguageTile(
            context,
            '한국어',
            const Locale('ko', 'KR'),
          ),
        ],
      ),
    );
  }

  Widget _buildLanguageTile(
    BuildContext context,
    String title,
    Locale locale,
  ) {
    // 获取当前语言
    final currentLocale = Localizations.localeOf(context);
    final isSelected = currentLocale.languageCode == locale.languageCode &&
        currentLocale.countryCode == locale.countryCode;

    return ListTile(
      title: Text(title),
      trailing: isSelected ? const Icon(Icons.check, color: Colors.green) : null,
      onTap: () async {
        // 保存设置
        await LanguageService.saveLanguage(locale);
        
        // 切换语言(根据使用的方案选择对应方法)
        // easy_localization:
        // context.setLocale(locale);
        
        // GetX:
        // Get.updateLocale(locale);
        
        // 其他方案可能需要重启 App 或使用状态管理
      },
    );
  }
}

使用 Provider 管理语言状态

// lib/providers/locale_provider.dart
import 'package:flutter/material.dart';
import '../services/language_service.dart';

class LocaleProvider extends ChangeNotifier {
  Locale _locale = const Locale('zh', 'CN');

  Locale get locale => _locale;

  LocaleProvider() {
    _loadSavedLocale();
  }

  Future<void> _loadSavedLocale() async {
    final savedLocale = await LanguageService.getSavedLanguage();
    if (savedLocale != null) {
      _locale = savedLocale;
      notifyListeners();
    }
  }

  Future<void> setLocale(Locale locale) async {
    if (_locale == locale) return;
    
    _locale = locale;
    await LanguageService.saveLanguage(locale);
    notifyListeners();
  }
}

// main.dart
void main() {
  runApp(
    ChangeNotifierProvider(
      create: (_) => LocaleProvider(),
      child: const MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    final localeProvider = context.watch<LocaleProvider>();

    return MaterialApp(
      locale: localeProvider.locale,
      localizationsDelegates: const [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        AppLocalizations.delegate,
      ],
      supportedLocales: const [
        Locale('zh', 'CN'),
        Locale('en', 'US'),
        Locale('ja', 'JP'),
      ],
      home: const HomePage(),
    );
  }
}

📅 日期和数字格式化

使用 intl 包格式化

import 'package:intl/intl.dart';

class FormatUtils {
  // 日期格式化
  static String formatDate(DateTime date, String locale) {
    return DateFormat.yMMMd(locale).format(date);
    // zh_CN: 2026年2月3日
    // en_US: Feb 3, 2026
    // ja_JP: 2026年2月3日
  }

  // 时间格式化
  static String formatTime(DateTime time, String locale) {
    return DateFormat.Hm(locale).format(time);
    // 14:30
  }

  // 日期时间格式化
  static String formatDateTime(DateTime dateTime, String locale) {
    return DateFormat.yMMMd(locale).add_Hm().format(dateTime);
    // zh_CN: 2026年2月3日 14:30
  }

  // 相对时间
  static String formatRelativeTime(DateTime dateTime) {
    final now = DateTime.now();
    final diff = now.difference(dateTime);

    if (diff.inDays > 365) {
      return '${diff.inDays ~/ 365}年前';
    } else if (diff.inDays > 30) {
      return '${diff.inDays ~/ 30}个月前';
    } else if (diff.inDays > 0) {
      return '${diff.inDays}天前';
    } else if (diff.inHours > 0) {
      return '${diff.inHours}小时前';
    } else if (diff.inMinutes > 0) {
      return '${diff.inMinutes}分钟前';
    } else {
      return '刚刚';
    }
  }

  // 数字格式化
  static String formatNumber(num number, String locale) {
    return NumberFormat.decimalPattern(locale).format(number);
    // 1234567 -> 1,234,567 (en_US)
    // 1234567 -> 1,234,567 (zh_CN)
  }

  // 货币格式化
  static String formatCurrency(num amount, String locale, String currency) {
    return NumberFormat.currency(
      locale: locale,
      symbol: currency,
    ).format(amount);
    // 1234.50 -> $1,234.50 (en_US, $)
    // 1234.50 -> ¥1,234.50 (zh_CN, ¥)
  }

  // 百分比格式化
  static String formatPercent(double value, String locale) {
    return NumberFormat.percentPattern(locale).format(value);
    // 0.75 -> 75%
  }
}

在 Widget 中使用

class FormattedDateWidget extends StatelessWidget {
  const FormattedDateWidget({super.key});

  @override
  Widget build(BuildContext context) {
    final locale = Localizations.localeOf(context).toString();
    final now = DateTime.now();

    return Column(
      children: [
        Text('日期:${FormatUtils.formatDate(now, locale)}'),
        Text('时间:${FormatUtils.formatTime(now, locale)}'),
        Text('价格:${FormatUtils.formatCurrency(1234.5, locale, '¥')}'),
        Text('数量:${FormatUtils.formatNumber(1234567, locale)}'),
      ],
    );
  }
}

📝 最佳实践

翻译文件管理

建议

  1. 使用 key 命名规范:模块_功能_描述,如 home_title、auth_login_button
  2. 避免硬编码:所有用户可见文本都应该国际化
  3. 保持翻译同步:使用工具检查遗漏的翻译
  4. 使用复数形式:不要用 1 items 这种错误形式
  5. 考虑文本长度:不同语言翻译后长度可能差异很大

文本长度处理

// 某些语言翻译后可能更长,要考虑溢出
Text(
  'very_long_text'.tr(),
  overflow: TextOverflow.ellipsis,
  maxLines: 2,
)

// 按钮文字也要考虑
ElevatedButton(
  onPressed: () {},
  child: FittedBox(
    fit: BoxFit.scaleDown,
    child: Text('submit_button'.tr()),
  ),
)

RTL(从右到左)语言支持

MaterialApp(
  // 支持 RTL 语言(如阿拉伯语、希伯来语)
  supportedLocales: const [
    Locale('en'),
    Locale('zh'),
    Locale('ar'),  // 阿拉伯语(RTL)
  ],
  localizationsDelegates: const [
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
    GlobalCupertinoLocalizations.delegate,
  ],
)

// 布局会自动调整方向
// 如果需要手动控制:
Directionality(
  textDirection: TextDirection.rtl,  // 或 TextDirection.ltr
  child: YourWidget(),
)

📊 方案对比总结

特性flutter_localizationsintl + ARBeasy_localizationGetX
官方支持✅✅❌❌
配置复杂度中高低低
代码生成❌✅❌❌
复数支持❌✅✅❌
热重载✅✅✅✅
JSON 支持❌❌✅❌
动态切换需手动需手动✅✅

推荐选择

  • 小型项目:easy_localization 或 GetX(简单快速)
  • 中型项目:flutter_localizations + 手动管理
  • 大型项目:intl + ARB(专业级,有代码生成)

💪 练习题

  1. 使用 easy_localization 实现中英文切换
  2. 使用 intl 包实现日期和货币的本地化显示
  3. 实现一个语言设置页面,保存用户的语言偏好
  4. 处理复数形式:「你有 N 条新消息」

🚀 下一步

掌握了国际化配置后,你可以前往 附录D - 权限处理,学习如何请求和管理应用权限!


由 编程指南 提供

最近更新: 2026/2/3 16:24
Contributors: 王长安
Prev
附录B - 项目结构最佳实践
Next
附录D - 权限处理