在这里插入图片描述

一、国际化基础

国际化(Internationalization,简称i18n)是指让应用能够适应不同语言、地区和文化。

国际化的重要性

35% 30% 20% 15% 国际化的价值 用户体验 市场拓展 品牌形象 合规要求

为什么需要国际化

  • 全球市场:应用面向不同国家和地区的用户
  • 用户友好:用户更愿意使用母语的应用
  • 合规要求:某些地区要求本地化
  • 商业价值:更好的用户体验带来更多用户

国际化组成部分

国际化

语言翻译

日期格式

数字格式

货币显示

文本方向

组成部分 说明 示例
语言翻译 文本翻译为不同语言 中英日韩
日期格式 适应不同地区的日期习惯 2025/01/19 vs 01/19/2025
数字格式 千位分隔、小数点格式 1,234.56 vs 1.234,56
货币显示 货币符号、金额格式 ¥123 vs $123
文本方向 LTR/RTL语言 英语vs阿拉伯语

Flutter国际化方案

Flutter提供了强大的国际化支持:

方案 特点 适用场景
flutter_localizations 官方方案 标准国际化
intl包 丰富的格式化 复杂格式化
自定义Provider 灵活控制 特殊需求
ARB文件 结构化翻译 翻译管理

InheritedWidget在国际化中的作用

  • 提供当前语言状态
  • 通知语言变化
  • 管理翻译资源
  • 处理RTL/LTR切换

二、案例概述

通过多语言切换示例学习InheritedWidget在国际化中的应用。

功能 说明
语言切换 支持中英文切换
文本翻译 所有文本自动翻译
RTL支持 自动切换文本方向
日期格式化 根据语言格式化日期
持久化存储 记住用户选择的语言

三、LocalizationProvider实现

class LocalizationProvider extends InheritedWidget {
  final Locale locale;
  final Function(Locale) changeLocale;

  const LocalizationProvider({
    required this.locale,
    required this.changeLocale,
    required Widget child,
  }) : super(child: child);

  static LocalizationProvider of(BuildContext context) {
    final LocalizationProvider? result = context
        .dependOnInheritedWidgetOfExactType<LocalizationProvider>();
    assert(result != null, 'No LocalizationProvider found');
    return result!;
  }

  bool get isZhCN => locale.languageCode == 'zh';
  bool get isEnUS => locale.languageCode == 'en';

  
  bool updateShouldNotify(LocalizationProvider oldWidget) {
    return locale != oldWidget.locale;
  }
}

四、翻译资源

class AppTranslations {
  static const Map<String, Map<String, String>> _translations = {
    'zh': {
      'app_title': '国际化示例',
      'welcome': '欢迎',
      'language': '语言',
      'chinese': '中文',
      'english': 'English',
      'date': '日期',
      'current_date': '当前日期',
      'settings': '设置',
      'about': '关于',
      'switch_language': '切换语言',
    },
    'en': {
      'app_title': 'i18n Example',
      'welcome': 'Welcome',
      'language': 'Language',
      'chinese': '中文',
      'english': 'English',
      'date': 'Date',
      'current_date': 'Current Date',
      'settings': 'Settings',
      'about': 'About',
      'switch_language': 'Switch Language',
    },
  };

  static String get(String key, Locale locale) {
    final langCode = locale.languageCode;
    return _translations[langCode]?[key] ?? key;
  }
}

五、语言切换流程

用户点击切换

changeLocale

setState更新locale

Provider重建

updateShouldNotify true

依赖组件重建

获取新翻译

更新UI

六、翻译助手组件

class LocalizedText extends StatelessWidget {
  final String key;
  final TextStyle? style;
  final TextAlign? textAlign;

  const LocalizedText(
    this.key, {
    super.key,
    this.style,
    this.textAlign,
  });

  
  Widget build(BuildContext context) {
    final provider = LocalizationProvider.of(context);
    final translated = AppTranslations.get(key, provider.locale);

    return Text(
      translated,
      style: style,
      textAlign: textAlign,
    );
  }
}

七、语言选择器组件

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

  
  Widget build(BuildContext context) {
    final provider = LocalizationProvider.of(context);

    return Card(
      child: ListTile(
        title: LocalizedText('language'),
        subtitle: Text(provider.isZhCN ? '中文' : 'English'),
        trailing: Switch(
          value: provider.isZhCN,
          onChanged: (value) {
            provider.changeLocale(value ? const Locale('zh') : const Locale('en'));
          },
        ),
      ),
    );
  }
}

八、日期格式化组件

class LocalizedDate extends StatelessWidget {
  final DateTime date;

  const LocalizedDate({super.key, required this.date});

  
  Widget build(BuildContext context) {
    final provider = LocalizationProvider.of(context);
    final formatted = provider.isZhCN
        ? '${date.year}${date.month}${date.day}日'
        : '${date.month}/${date.day}/${date.year}';

    return Text(formatted);
  }
}

九、主页面组件

InternationalizationExample

LocalizationProvider

AppBar

欢迎卡片

语言选择器

日期显示

功能列表

十、完整示例

class InternationalizationExample extends StatefulWidget {
  const InternationalizationExample({super.key});

  
  State<InternationalizationExample> createState() => _InternationalizationExampleState();
}

class _InternationalizationExampleState extends State<InternationalizationExample> {
  Locale _locale = const Locale('zh');

  
  Widget build(BuildContext context) {
    return LocalizationProvider(
      locale: _locale,
      changeLocale: (newLocale) {
        setState(() {
          _locale = newLocale;
        });
      },
      child: Scaffold(
        appBar: AppBar(
          title: LocalizedText('app_title'),
          actions: [
            IconButton(
              icon: const Icon(Icons.language),
              onPressed: () {
                final provider = LocalizationProvider.of(context);
                provider.changeLocale(
                  provider.isZhCN ? const Locale('en') : const Locale('zh'),
                );
              },
            ),
          ],
        ),
        body: Padding(
          padding: const EdgeInsets.all(16),
          child: Column(
            children: [
              _buildWelcomeCard(),
              const SizedBox(height: 16),
              const LanguageSelector(),
              const SizedBox(height: 16),
              _buildDateSection(),
              const SizedBox(height: 16),
              _buildFeatureList(),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildWelcomeCard() {
    return Container(
      padding: const EdgeInsets.all(24),
      decoration: BoxDecoration(
        gradient: LinearGradient(
          colors: [
            Theme.of(context).colorScheme.primary,
            Theme.of(context).colorScheme.secondary,
          ],
        ),
        borderRadius: BorderRadius.circular(12),
      ),
      child: Column(
        children: [
          const Icon(Icons.public, size: 64, color: Colors.white),
          const SizedBox(height: 16),
          LocalizedText(
            'welcome',
            style: const TextStyle(fontSize: 32, color: Colors.white),
          ),
        ],
      ),
    );
  }

  Widget _buildDateSection() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            LocalizedText('current_date', style: const TextStyle(fontSize: 18)),
            const SizedBox(height: 8),
            LocalizedDate(date: DateTime.now()),
          ],
        ),
      ),
    );
  }

  Widget _buildFeatureList() {
    return Card(
      child: Column(
        children: [
          ListTile(
            leading: const Icon(Icons.settings),
            title: LocalizedText('settings'),
          ),
          ListTile(
            leading: const Icon(Icons.info),
            title: LocalizedText('about'),
          ),
        ],
      ),
    );
  }
}

十一、国际化最佳实践

国际化最佳实践

资源管理

统一管理翻译

使用常量类

按模块划分

性能优化

缓存翻译结果

懒加载语言包

减少重建次数

用户体验

平滑切换动画

记住用户选择

提供语言预览

代码组织

提取翻译助手

封装通用组件

保持代码简洁

最佳实践 说明 效果
统一管理翻译 使用Map或类管理所有翻译 易于维护和扩展
封装翻译组件 创建LocalizedText等组件 简化使用代码
RTL支持 考虑阿拉伯语等语言 提升国际化程度
持久化存储 使用SharedPreferences存储 记住用户选择
懒加载语言包 按需加载翻译资源 减少初始加载时间

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐