这次学习实践如何在鸿蒙App中通过Flutter框架实现多语言环境适配

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

如果项目需要支持多语言,在Flutter框架下鸿蒙如何实现呢?,往下看。

功能实现 - 多语言(中文 / 英文)

在这里插入图片描述

一、期望目标

  • 目标:应用支持中文、英文两种语言,界面文案随语言切换;用户可在设置中选择语言或跟随系统,选择结果持久化并在下次启动生效。
  • 方案
    • 使用 Flutter 官方 gen-l10n 方案:flutter_localizations + ARB 文案文件,通过 flutter gen-l10n 生成 AppLocalizations
    • main.dart 中注册 localizationsDelegatessupportedLocales,并用全局 ValueNotifier<Locale?>(null 表示跟随系统)驱动 MaterialApp.locale
    • SettingsService 持久化语言偏好(zh / en 或未设置即跟随系统);设置页增加「语言」入口,底部弹层选择「跟随系统 / 中文 / English」后更新 Notifier 并持久化,整应用即时切换语言。
    • 所有用户可见文案从各页面的硬编码中文改为 AppLocalizations.of(context)!.xxx,保证中英一致覆盖。

二、依赖与配置

2.1 依赖

文件pubspec.yaml

  • 新增:flutter_localizations: sdk: flutter
  • flutter: 下增加 generate: true,以启用 l10n 代码生成。

2.2 l10n 配置

文件l10n.yaml(项目根目录)

arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
output-class: AppLocalizations

2.3 文案文件

  • lib/l10n/app_en.arb:英文模板,包含全部 key 及占位符(如 loadFailed{error}minutesAgo{n})。
  • lib/l10n/app_zh.arb:中文翻译,key 与模板一致,@@locale": "zh"

生成命令:在项目根目录执行 flutter gen-l10n,产物位于 .dart_tool/flutter_gen/gen_l10n/,通过 import 'package:flutter_gen/gen_l10n/app_localizations.dart'; 使用。

三、实现说明

3.1 设置服务:语言持久化

文件lib/services/settings_service.dart

  • 新增存储键:_keyLocale = 'settings_locale',取值:'zh' / 'en',未设置或空表示跟随系统。
  • 新增方法:
    • Future<Locale?> getLocale():读取本地存储,默认返回 null(跟随系统)。
    • Future<void> setLocale(Locale? locale):写入或移除键以持久化。

3.2 应用入口:多语言与启动加载

文件lib/main.dart

  • 启动流程:在 runApp 前除读取主题模式外,增加 SettingsService().getLocale() 得到初始语言,并创建 appLocaleNotifier = ValueNotifier<Locale?>(initialLocale)
  • MaterialApp
    • 在原有 ValueListenableBuilder<ThemeMode> 内再包一层 ValueListenableBuilder<Locale?>,将 appLocaleNotifier.value 赋给 locale(null 时由 Flutter 使用系统语言)。
    • 设置 localizationsDelegatesAppLocalizations.delegateGlobalMaterialLocalizations.delegateGlobalWidgetsLocalizations.delegateGlobalCupertinoLocalizations.delegate
    • 设置 supportedLocalesLocale('en')Locale('zh')

3.3 设置页:语言入口与选择弹层

文件lib/pages/profile_page.dart

  • 在设置二级页 ListView 中增加 「语言」 入口(置于外观之上):
    • 标题:使用 l10n.language;副标题:当前语言文案(跟随系统 / 中文 / English),由 _localeLabel(context) 根据 appLocaleNotifier.value 计算。
    • 点击后弹出底部弹层,三个 RadioListTile<String>:跟随系统(themeSystem)、中文(languageChinese)、English(languageEnglish),groupValue 为当前选中的 'system' / 'zh' / 'en'
  • 选择后关闭弹层,将结果转为 Locale?'system' → null),更新 appLocaleNotifier.value 并调用 SettingsService().setLocale(newLocale),界面立即重建为所选语言。
  • 设置页内其余文案(外观、隐私与安全、清除缓存、设置标题、缓存结果 SnackBar、退出登录对话框等)全部改为使用 AppLocalizations.of(context)!;主题模式弹层与 _themeModeLabel 改为接收 AppLocalizations 以输出中/英标签。

3.4 各页文案本地化

以下页面将硬编码中文替换为 AppLocalizations.of(context)! 或传入的 l10n,并在异步回调中注意 mounted 与 context 使用安全(先 if (!mounted) return; 再取 l10n):

文件 修改要点
root_page.dart 底部导航四个 Tab 的 label:首页/发现/消息/我的 → tabHome / tabSearch / tabMessages / tabProfile
home_page.dart 加载失败文案 loadFailed(e)、重试按钮 retry、暂无数据 noData;catch 内先 mounted 再取 l10n
search_page.dart 搜索 hint searchHint、重试 retry、暂无作品/未找到 noWorks / noMatchingWorks、加载失败 loadFailed(e)
messages_page.dart 消息标题、新建会话对话框(标题、hint、取消/添加)、会话名称校验与 SnackBar、点击进入聊天、暂无消息、时间格式 minutesAgo/hoursAgo/daysAgo; mock 会话名称与最后一条消息使用 l10n(设计小助手、系统通知、创作交流群等);聊天详情输入框 hint、欢迎语 chatGreeting(name)
profile_page.dart 我的、示例用户 sampleUser、获赞/收藏、我的收藏/历史/设置/退出登录及副标题、历史记录页标题与暂无浏览记录、设置头标题、清除缓存结果、退出确认对话框全文
favorites_page.dart 我的收藏标题、暂无收藏 noFavorites
work_detail_page.dart 暂无图片 noImages
privacy_settings_page.dart 隐私与安全标题、隐私政策/用户协议/账号与安全标题及正文(privacyPolicyContent / termsContent / accountSecurityContent
notification_settings_page.dart 通知设置标题、接收通知/新消息通知/点赞与收藏通知的标题与副标题
upload_page.dart 发布内容标题、标题/描述 label、校验文案、发布按钮、发布成功 SnackBar;异步中 mounted 后再 SnackBar

四、使用说明

  1. 打开应用 → 底部「我的」→ 进入「设置」。
  2. 点击 「语言」(或 “Language”),在底部弹层中选择:
    • 跟随系统:与系统语言一致(如系统为英文则应用为英文);
    • 中文:固定为简体中文;
    • English:固定为英文。
  3. 选择后立即生效,且下次启动会保持上次选择。

五、涉及文件一览

文件 变更类型
pubspec.yaml 新增 flutter_localizationsgenerate: true
l10n.yaml 新建,arb 目录与模板配置
lib/l10n/app_en.arb 新建,英文模板
lib/l10n/app_zh.arb 新建,中文翻译
lib/services/settings_service.dart 新增 getLocale / setLocale_keyLocale
lib/main.dart 启动加载 locale、appLocaleNotifierlocalizationsDelegatessupportedLocaleslocale
lib/pages/root_page.dart Tab 文案改为 l10n
lib/pages/home_page.dart 错误/重试/暂无数据 l10n,catch 内 mounted + l10n
lib/pages/search_page.dart 搜索 hint、重试、空状态、loadFailed l10n
lib/pages/messages_page.dart 消息/会话/聊天相关全部 l10n,mock 数据与时间格式
lib/pages/profile_page.dart 语言入口与弹层、设置与个人页全部 l10n、主题弹层 l10n
lib/pages/favorites_page.dart 我的收藏、暂无收藏 l10n
lib/pages/work_detail_page.dart 暂无图片 l10n
lib/pages/privacy_settings_page.dart 标题与三段正文 l10n
lib/pages/notification_settings_page.dart 标题与三个开关标题/副标题 l10n
lib/pages/upload_page.dart 发布页全部 l10n,异步 SnackBar 前 mounted

六、开发与维护说明

  • 新增或修改文案:在 app_en.arb 中增改 key(含占位符时需补 @keyplaceholders),在 app_zh.arb 中同步增改;随后执行 flutter gen-l10n
  • 新增语言:在 lib/l10n/ 下新增 app_<locale>.arb,并在 main.dartsupportedLocales 中增加对应 Locale
  • 所有用户可见字符串应通过 AppLocalizations 获取,避免在 UI 中硬编码中/英文。
结束语

感谢阅读本帖,如对贴中内容有意见和建议的,欢迎与我联系交流,也欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐