Flutter 鸿蒙化一步到位:跟随手机语言、切语言免重启、RTL 自动排版,一个原生接口即取即用零权限 —— app_local 鸿蒙使用指南
什么是 App 本地化(i18n)?**
应用面向全球用户时,界面文案需要按用户语言动态呈现:首次启动跟随手机语言、设置页随时切换、阿拉伯语等 RTL(从右向左)语言自动镜像排版。传统 Flutter i18n 方案(
intl+arb+ 代码生成)链路繁琐,而 app_local 只需要几份 JSON 翻译文件 + 一行初始化,就能拿到全部能力。
适配鸿蒙的关键只有一点:"手机语言"这个系统能力必须由原生提供。Android 走 Locale.getDefault()、iOS 走 Locale.preferredLanguages,鸿蒙则对应 i18n.System.getSystemLanguage()——语义对齐、同样零权限,接上通道后上层 API 一行不改。
开发工具:华为云码道(DevEco Studio)
配套仓库:原库 abom-me/app_local(pub 包名 app_local,版本 1.1.3),鸿蒙适配版 https://atomgit.com/CPF-Flutter/fluttertpc_app_local(TAG:1.1.3-ohos-1.0.0-beta.1,分支 br_v1.1.3_ohos)
一、最终运行效果
示例 App 支持英语 / 中文 / 阿拉伯语三种语言,启动后以默认语言(英语)展示:
页面包含:
- 欢迎横幅:
LocaleText('welcome')大标题 + 带占位符参数的问候语LocaleText('greeting', params: [...])——“Hello EN, welcome to app_local!”,其中EN与app_local是运行时注入的两个参数; - Runtime state 卡片:设备语言(
Locales.deviceLocale,真机上正确识别为 zh)、当前语言(en)、文字方向(LTR)、支持的语言列表; - API features 卡片:四项能力自检(LocaleText 组件、BuildContext 扩展、占位符参数、免重启切换),全部绿勾;
- Available keys 卡片:当前语言 JSON 里已加载的 26 个键,以 Chip 列表展示;
- 快捷切换按钮:English / Chinese / Arabic 三个按钮。
点击 Chinese 按钮,整个页面瞬间切换为中文,无需重启、无需 setState 逐层传递:
点击 Arabic 按钮,页面自动镜像为从右向左排版,阿拉伯语文案正确渲染——RTL 判断由 intl.Bidi.isRtlLanguage 在 Dart 层完成,各平台行为一致:
验证点结果一览:
| 验证点 | 结果 |
|---|---|
插件注册(Adding plugin: AppLangPlugin) | ✅ 通过 |
通道注册 app_lang | ✅ 通过 |
getPhoneLanguage 通道调用(初始化时两次) | ✅ 通过 |
设备语言识别(zh-CN 真机 → zh) | ✅ 通过 |
| 运行时切换 EN → 中文(免重启、整页即时生效) | ✅ 通过 |
| 阿拉伯语 RTL 镜像排版 | ✅ 通过 |
占位符参数注入(## / ###) | ✅ 通过 |
| 全程无需申请任何敏感权限 | ✅ 通过 |
鸿蒙技术点:FlutterPage 与 XComponent 渲染管线
与所有 Flutter 鸿蒙化工程一致:
Index.ets的@Entry组件在build()中使用FlutterPage(内部封装XComponent渲染画布,经 NAPI 桥接 C++ 引擎层);EntryAbility继承FlutterAbility,在configureFlutterEngine中GeneratedPluginRegistrant.registerWith(flutterEngine)完成插件注册——AppLangPlugin由此挂进引擎。
二、app_local 是什么
原库(pub 包 app_local,作者 abom)是一个轻量级 App 本地化框架:翻译内容放在 assets/lang/xx.json,初始化一次后即可用 LocaleText 组件、Locales.string() 或 BuildContext/String 扩展按键取文案,支持运行时切换、占位符参数、RTL 检测与语言偏好持久化。
鸿蒙适配版新增 ohos 平台:Dart 层公开 API 零改动,OpenHarmony 侧提供 ArkTS 插件 AppLangPlugin,实现 app_lang 方法通道上的 getPhoneLanguage 一个方法。
使用者友好特点(分条):
- JSON 即翻译:每个语言一个
xx.json,键值对维护,无需代码生成; - 一行初始化:
Locales.init()搞定语言探测、偏好读取、代理注册; - 免重启切换:基于
InheritedWidget通知整棵组件树重建,切语言即时生效; - 三族取文本 API:
LocaleText组件 /Locales.string()静态方法 /context.localeString()与key.localize()扩展,按场景任选; - 占位符参数:
"greeting": "Hello ##, welcome to ###!"+params: [a, b],参数本身还可以是本地化键; - RTL 自动处理:
isDirectionRTL()与LocaleText均基于intl.Bidi,阿拉伯语开箱即得; - 鸿蒙零权限:
getPhoneLanguage走i18n.System.getSystemLanguage(),系统语言查询接口,无需申请任何权限。
接口说明
Locales 静态接口:
| 接口 | 说明 |
|---|---|
Locales.init(localeNames, localPath, phoneLocale) | 初始化:注册支持语言、读取翻译目录、phoneLocale: true 时首启跟随手机语言 |
Locales.string(context, key, params, localeParams) | 按键取本地化文本 |
Locales.change(context, lang) / context.changeLocale(lang) | 运行时切换语言 |
Locales.currentLocale(context) / Locales.lang | 当前 Locale / 当前语言码 |
Locales.deviceLocale | 设备语言码(来自原生通道) |
Locales.isDirectionRTL(context) / Locales.selectedLocaleRtl | 是否从右向左 |
Locales.delegates / Locales.delegate | 交给 MaterialApp 的本地化代理(已合并 Material/Cupertino/Widgets 全家桶) |
Locales.of(context) | 取 Locales 实例(含 availableKeys、hasKey、reload) |
组件:
| 组件 | 说明 |
|---|---|
LocaleBuilder | 包住 MaterialApp,语言变化时用新 Locale 重建子树 |
LocaleText | Text 的本地化子类,k 为翻译键,支持 params、upperCase、style 等 |
AppLang(平台通道):
| 方法 | 返回 | 说明 |
|---|---|---|
AppLang().getPhoneLanguage() | Future<String?> | 设备语言的 BCP-47 标签(如 zh-Hans、en-US);Web/异常时兜底 en-OM |
各平台设备语言路径表
| 平台 | 实现方式 | 返回示例 |
|---|---|---|
| Android | Locale.getDefault().toLanguageTag() | zh-CN |
| iOS / macOS | Locale.preferredLanguages.first | zh-Hans-CN |
| OpenHarmony(本文) | i18n.System.getSystemLanguage() | zh-Hans |
| Web / 其它 | Dart 层兜底 | en-OM |
说明:Dart 层只取标签第一段(
split("-").first),因此zh-Hans与zh-CN对上层完全等价。
三、环境准备
本文实测环境:
| 环境项 | 版本 |
|---|---|
| Flutter(ohos 版) | 3.47.7-ohos-1.0.0(channel oh-3.47-dev,Dart 3.13.3) |
| DevEco Studio | 26.0.0(本机 SDK API 26) |
| 编译 SDK | 6.1.1(24)(compatibleSdkVersion / targetSdkVersion) |
| 真机 | 华为 TLR-AL00,HarmonyOS 6.1.0.145(C00E120R3P5),API 24(系统语言 zh-CN) |
鸿蒙技术点:compatibleSdkVersion 与 API Level 对应关系
example/ohos/build-profile.json5关键字段为"compatibleSdkVersion": "6.1.1(24)"、"targetSdkVersion": "6.1.1(24)"(保留括号旧格式)。系统校验应用声明的兼容版本不得高于设备 API,否则安装时报"此应用暂不支持在当前设备安装"。本机 DevEco SDK 为 API 26,向下兼容 API 24 的目标设备。
两点提醒:
- 需要 ohos 版 Flutter SDK(本文使用 3.47.7-ohos-1.0.0);
- 真机安装报错大多与
compatibleSdkVersion过高有关,与插件无关,见 FAQ Q5。
四、引入依赖
在工程 pubspec.yaml 中添加 git 依赖:
...
dependencies:
app_local:
git:
url: https://atomgit.com/CPF-Flutter/fluttertpc_app_local
# ref: 1.1.3-ohos-1.0.0-beta.1
ref: TAG # 请根据下方TAG版本对应表选择TAG
...
执行命令:
flutter pub get
TAG 版本对应表
| Flutter 框架版本 | TAG | 分支 |
|---|---|---|
| 3.47 | 1.1.3-ohos-1.0.0-beta.1 | br_v1.1.3_ohos |
TAG 命名规则:
原库版本-ohos-版本号。原库 1.1.3 对应1.1.3-ohos-1.0.0-beta.1(分支br_v1.1.3_ohos)。
依赖链方面:shared_preferences(Flutter 官方插件)与 intl(纯 Dart)在鸿蒙上均可解析,flutter_localizations 来自 SDK,无额外原生依赖。
五、代码接入
5.1 准备翻译 JSON
在 assets/lang/ 下按语言码各放一份 JSON(示例工程放在 assets/a/):
// assets/lang/zh.json
{
"localization": "本地化",
"welcome": "欢迎",
"greeting": "你好 ##,欢迎来到 ###!",
"device_language": "设备语言",
"chinese": "中文",
"english": "英语",
"arabic": "阿拉伯语"
}
并在 pubspec.yaml 中声明 assets:
flutter:
assets:
- assets/lang/
键名建议全小写下划线风格——库会自动归一化(空格转下划线、转小写),大小写混写也不怕。
5.2 导入并初始化
import 'package:app_local/app_local.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Locales.init(
localeNames: ['en', 'ar', 'zh'], // 支持的语言
localPath: "assets/lang/", // 翻译文件目录
phoneLocale: true, // 首次启动跟随手机语言
); // 内部会读取上次保存的语言偏好
runApp(const MyApp());
}
代码逐段分析:init 都做了什么
- 校验
localeNames非空,规范化翻译目录路径(补末尾/);- 调
AppLang().getPhoneLanguage()取设备语言——鸿蒙上这一步走 ArkTS 通道i18n.System.getSystemLanguage(),真机上返回zh-Hans,Dart 取第一段得zh;phoneLocale: true时用设备语言初始化(不支持则回退到列表第一个),否则读取持久化偏好;- 全程 try/catch,出错不会让 App 起不来。
5.3 LocaleBuilder 接入 MaterialApp
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return LocaleBuilder(
builder: (locale) => MaterialApp(
title: 'Flutter Locales',
localizationsDelegates: Locales.delegates, // 四个代理一次配齐
supportedLocales: Locales.supportedLocales,
locale: locale, // 语言变化时 LocaleBuilder 重建并下发新 locale
home: HomeScreen(),
),
);
}
}
Locales.delegates 已合并 Locales.delegate 与 Material / Cupertino / Widgets 三个全局代理,M3 组件的内置文案(日期选择器、对话框按钮等)也会跟着切换。
5.4 三种方式取文本
// ① LocaleText 组件(推荐,最省事)
LocaleText('welcome', style: TextStyle(fontSize: 28))
LocaleText('greeting', params: [Locales.lang.toUpperCase(), 'app_local'])
// ② Locales.string 静态方法(任意位置可用)
Text(Locales.string(context, 'switch_language'))
// ③ BuildContext / String 扩展
Text(context.localeString('about'))
Text('about'.localize(context))

代码逐段分析:占位符的规则
"greeting": "你好 ##,欢迎来到 ###!"中##是第 1 个参数、###是第 2 个参数(井号个数 = 参数序号)。替换时若localeParams传入的值能在翻译表中命中键名,则会先做本地化再注入——比如把"chinese"作为参数传入,中文环境下注入的是"中文"而不是"chinese"。剩余未匹配的#最后统一清除。
5.5 运行时切换语言
// 任意位置一行调用,整棵组件树即时重建
context.changeLocale('zh');
// 回到"跟随手机语言"
context.changeLocale('auto');

切换逻辑在 PreferenceUtils.setLocale:更新 Locales.selectedLocale → 写入偏好 → LocaleBuilder setState 触发 MaterialApp 用新 Locale 重建 → LocalesDelegate.load() 加载对应 JSON。无需重启、无需手动 setState。
注意:切换目标必须是 Locales.init(localeNames: [...]) 里注册过的语言(或 'auto'),否则会打日志忽略这次切换——防止手滑传错语言码导致白屏。
5.6 RTL 与语言元信息
final bool isRtl = Locales.isDirectionRTL(context);
Text(Locales.selectedLocaleRtl ? 'RTL' : 'LTR');
RTL 判断用 intl.Bidi.isRtlLanguage(纯 Dart),阿拉伯语环境下布局自动镜像,无需逐个写 TextDirection.rtl。

5.7 实战:语言设置页
把切换、当前态、跟随手机语言整合成一个设置页:
class SettingScreen extends StatelessWidget {
const SettingScreen({super.key});
Widget build(BuildContext context) {
final String? current = Locales.currentLocale(context)?.languageCode;
final Map<String, String> options = {
'en': Locales.string(context, 'english'),
'ar': Locales.string(context, 'arabic'),
'zh': Locales.string(context, 'chinese'),
'auto': Locales.string(context, 'auto'), // 跟随手机语言
};
return Scaffold(
appBar: AppBar(title: LocaleText('setting')),
body: ListView(
children: options.entries.map((entry) => ListTile(
title: Text(entry.value),
trailing: current == entry.key
? const Icon(Icons.check_circle)
: null,
onTap: () => context.changeLocale(entry.key), // 一行切换
)).toList(),
),
);
}
}
三点心得:动态色……不对,是三条配置原则——phoneLocale: true 让首启体验国际化、设置页提供 auto 选项让用户随时改主意、选项列表直接从翻译表取文案,新加一门语言只需要新增一个 JSON 和一个语言码。

六、运行与验证
Demo Bundle Name:com.abom.app_local_example;设备:华为 TLR-AL00,HarmonyOS 6.1.0.145(API 24),系统语言 zh-CN。打包产物 entry-default-signed.hap(约 118 MB)。
6.1 验证一:安装与启动
hdc install -r entry-default-signed.hap
# [Info]App install path:...entry-default-signed.hap msg:install bundle successfully.
hdc shell aa start -a EntryAbility -b com.abom.app_local_example
# start ability successfully.
启动后即见第一节截图的英语首页。

6.2 验证二:插件注册与通道调用日志
hdc shell hilog | grep AppLangPlugin
10-20 23:27:57.005 W A000FF/...Flutter: FlutterEngineCxnRegistry --> Adding plugin: AppLangPlugin
10-20 23:27:57.005 I A00000/...AppLangPlugin: attached to engine, channel [app_lang] registered
10-20 23:27:57.258 D A00000/...AppLangPlugin: onMethodCall: getPhoneLanguage
10-20 23:27:57.277 D A00000/...AppLangPlugin: onMethodCall: getPhoneLanguage
getPhoneLanguage 被调用了两次——一次来自 Locales.init、一次来自 PreferenceUtils.init,都命中鸿蒙原生通道(而非 en-OM 兜底),说明 Platform.isOhos 分支生效。

6.3 验证三:设备语言识别
"Runtime state"卡片显示 Device language: zh——真机系统语言为 zh-CN,原生侧返回 zh-Hans 标签、Dart 层取第一段 zh,识别正确。
6.4 验证四:免重启切换与 RTL
真机上依次点击底部 Chinese 与 Arabic 按钮:
- 点击 Chinese:整页瞬间切为中文(标题"本地化"、问候语"你好 ZH,欢迎来到 app_local!"),过程无重启、无闪屏;
- 点击 Arabic:页面整体镜像为从右向左排版,AppBar 标题"اللغة"靠右,按钮组反向排列——RTL 生效。
6.5 验证五:语言偏好持久化(重要发现)
aa force-stop 后重新启动,App 回到了默认的英语——即当前示例工程下语言选择没有跨重启记忆。
原因:语言偏好经 shared_preferences 持久化,而示例工程的依赖树里只有 shared_preferences_android/foundation/linux/web/windows 等实现,没有鸿蒙侧的 shared_preferences_ohos 平台实现,SharedPreferences.getInstance() 在鸿蒙上拿不到存储。库对此早有兜底设计(PreferenceUtils 里 try/catch + _runtimeLocale 运行时记忆),所以切换功能本身完全不受影响,只是重启后不记得上次的选择。
解决方案见 FAQ Q3:引入鸿蒙社区的 shared_preferences_ohos 实现后即可恢复持久化。
实测结论表
| # | 验证点 | 结果 |
|---|---|---|
| 1 | HAP 真机安装成功(compatibleSdkVersion 6.1.1(24)) | 通过 |
| 2 | 插件注册与 app_lang 通道挂载 | 通过 |
| 3 | getPhoneLanguage 走鸿蒙原生通道(两次调用) | 通过 |
| 4 | 设备语言识别 zh-CN → zh | 通过 |
| 5 | 运行时切换 EN → ZH 免重启即时生效 | 通过 |
| 6 | 阿拉伯语 RTL 镜像排版 | 通过 |
| 7 | 占位符参数注入 | 通过 |
| 8 | 语言偏好跨重启持久化(当前示例) | ❌ 未通过(缺 shared_preferences_ohos,见 FAQ Q3) |
| 9 | 全程无需申请任何敏感权限 | 通过 |
七、工作原理
调用链路
main()
└─ Locales.init(localeNames, localPath, phoneLocale)
├─ AppLang().getPhoneLanguage()
│ └─ MethodChannel('app_lang') ──▶ ArkTS AppLangPlugin
│ └─ i18n.System.getSystemLanguage() // 鸿蒙
│ (Android: Locale.getDefault() / iOS: preferredLanguages)
├─ PreferenceUtils.init()(读偏好 + 设备语言)
└─ selectedLocale = 偏好 ?? 手机语言 ?? 列表第一项
runApp()
└─ LocaleBuilder(StatefulWidget,持有当前 Locale)
└─ LocaleNotifier(InheritedWidget)
└─ MaterialApp(locale: ...)
└─ LocalesDelegate.load() → rootBundle 读 JSON → Locales 实例
context.changeLocale('zh')
└─ LocaleNotifier.of(context).change('zh')
└─ _LocaleBuilderState.setState()
└─ MaterialApp 重建 → 全部文案即时切换
代码逐段分析:Platform.isOhos 分支——适配中最关键的坑
Dart 侧方法通道实现(
app_lang_method_channel.dart)原本只在 Android/iOS/macOS 上发起通道调用:if (Platform.isAndroid || Platform.isIOS || Platform.isMacOS) { final version = await methodChannel.invokeMethod<String>('getPhoneLanguage'); return version; } return "en-OM";如果只写 ArkTS 插件而不改这段 Dart,鸿蒙上原生通道永远不会被调用,设备语言恒为兜底值
en-OM。适配版补上了Platform.isOhos分支(Flutter-OHOS 引擎提供的平台判断):if (Platform.isAndroid || Platform.isIOS || Platform.isMacOS || Platform.isOhos) { final version = await methodChannel.invokeMethod<String>('getPhoneLanguage'); return version; }这是所有 Flutter 鸿蒙化插件适配中都要警惕的一类问题——平台判断白名单里没有 ohos,原生写得再好也是空转。
OHOS 插件实现
ArkTS 侧插件(ohos/src/main/ets/components/plugin/AppLangPlugin.ets)核心逻辑:
const CHANNEL_NAME: string = 'app_lang';
const METHOD_GET_PHONE_LANGUAGE: string = 'getPhoneLanguage';
export default class AppLangPlugin implements FlutterPlugin, MethodCallHandler {
private channel: MethodChannel | null = null;
onAttachedToEngine(binding: FlutterPluginBinding): void {
this.channel = new MethodChannel(binding.getBinaryMessenger(), CHANNEL_NAME);
this.channel.setMethodCallHandler(this);
hilog.info(DOMAIN, TAG,
'attached to engine, channel [%{public}s] registered', CHANNEL_NAME);
}
onDetachedFromEngine(binding: FlutterPluginBinding): void {
// 置空 handler,避免引擎销毁后插件实例仍被通道持有而无法释放
this.channel?.setMethodCallHandler(null);
this.channel = null;
}
private getPhoneLanguage(): string {
const language: string = i18n.System.getSystemLanguage();
if (language != null && language.length > 0) {
return language; // 如 'zh-Hans'、'en-Latn-US'
}
return 'en'; // 兜底,与 Dart 层默认语义一致
}
}
鸿蒙技术点:i18n.System.getSystemLanguage 的选型
OpenHarmony 没有与 Android
Locale.getDefault()完全对等的 API,最贴近"手机语言"语义的是i18n.System.getSystemLanguage()(返回系统语言标签如zh-Hans);备选的i18n.System.getSystemLocale()返回带地区的完整区域(zh-Hans-CN),语义偏"区域"而非"语言"。由于 Dart 层只取第一段,两者对上层等价,故选语义更贴切的前者。该接口无需申请任何权限。
插件的注册同样由工具链完成:pubspec.yaml 中的
flutter:
plugin:
platforms:
ohos:
pluginClass: AppLangPlugin
声明会让 ohos 版 Flutter 工具链生成 GeneratedPluginRegistrant,在 EntryAbility.configureFlutterEngine 中自动注册。
代码逐段分析:LocaleNotifier 与 InheritedWidget
LocaleBuilder持有当前Locale并包一层LocaleNotifier(InheritedWidget)。切换语言时changeLocale()走setState更新 Locale → 依赖该 InheritedWidget 的子树(整个 MaterialApp)重建 →LocalizationsDelegate.load()重新加载对应语言的 JSON。updateShouldNotify恒返回 true,保证任何语言变化都通知到位。这套机制纯 Dart 实现,鸿蒙与其它平台行为完全一致。
八、常见问题
Q1:app_local 和 intl/arb 官方方案怎么选?
官方 intl + .arb 方案功能全(复数、日期、货币格式化)但链路重(代码生成、重建);app_local 胜在极简——JSON 即翻译、运行时切换零成本,适合文案为主的中小型应用。两者可共存:文案用 app_local,日期数字格式化仍用 intl。
Q2:切换语言后为什么有些文案没变?
LocaleText / Locales.string 都会即时响应;但在 Locales.init 之前缓存了文案、或把翻译结果存进了状态变量的地方需要自查。另外新加的语言必须写进 Locales.init(localeNames: [...]),热重载不会重跑 main(),要整包重启才能注册新语言。
Q3:鸿蒙上重启后语言回到了默认值?
当前示例的依赖树里没有 shared_preferences_ohos(只有 Android/iOS/桌面/Web 实现),偏好写入在鸿蒙上不生效。引入鸿蒙社区 flutter_packages 仓库中的 shared_preferences_ohos 平台实现(并在 dependency_overrides 中挂接)后即可恢复持久化。在此之前,库的兜底设计保证运行时切换完全正常,只是不记忆。
Q4:getPhoneLanguage 返回 en-OM 是怎么回事?
en-OM 是 Dart 层的兜底值,出现它说明通道没走通。在鸿蒙上重点检查两点:① 依赖必须是本鸿蒙适配版 TAG(内含 Platform.isOhos 分支修复);② GeneratedPluginRegistrant 中已注册 AppLangPlugin(可 hdc shell hilog | grep AppLangPlugin 验证)。
Q5:真机安装报"此应用暂不支持在当前设备安装"?
检查 build-profile.json5 的 compatibleSdkVersion,必须不高于目标设备 API(API 24 设备对应 6.1.1(24),保留括号旧格式)。与插件无关。
Q6:通道名为什么叫 app_lang 而不是 app_local?
app_lang 是原库定下的原生通道契约(对应原生插件类 AppLangPlugin),Dart 包名才是 app_local。鸿蒙适配版严格沿用 app_lang,与 Android/iOS/macOS 实现保持一致。
九、结语
回顾一下:git TAG 引入依赖 → assets/lang/ 放 JSON → Locales.init() 一行初始化 → LocaleBuilder 包住 MaterialApp → LocaleText / context.localeString 取文案 / context.changeLocale 切语言。
核心结论:
- 鸿蒙上设备语言识别、运行时切换、RTL 排版全部实测通过,
getPhoneLanguage走i18n.System.getSystemLanguage(),与 Android/iOS 语义对齐,零权限; - 适配中最关键的一处修改是 Dart 层补上
Platform.isOhos平台分支——没有它,原生通道在鸿蒙上永远不会被调用; - 语言偏好的跨重启持久化依赖
shared_preferences的鸿蒙实现,当前示例未引入shared_preferences_ohos时切换功能不受影响,但重启后回到默认语言(已如实记录在实测结论表); - 已在华为真机(HarmonyOS 6.1.0.145 / API 24)完整实测,除持久化一项待补平台实现外全部通过。
欢迎提 Issue / PR 共建。
相关链接
- 鸿蒙适配版仓库:
https://atomgit.com/CPF-Flutter/fluttertpc_app_local(TAG1.1.3-ohos-1.0.0-beta.1) - 原库:
https://github.com/abom-me/app_local - OpenHarmony i18n 文档(
@ohos.i18n):https://developer.huawei.com/consumer/cn/doc/ - 鸿蒙社区 Flutter 插件仓库(含
shared_preferences_ohos):https://gitee.com/openharmony-sig/flutter_packages - Flutter 鸿蒙化开发环境:
https://atomgit.com/oh-flutter/flutter_flutter
附:app_local 核心能力对照表
| 能力维度 | 实现方式 | 鸿蒙表现 | 跨平台一致性 |
|---|---|---|---|
| 设备语言识别 | 原生通道 getPhoneLanguage | ✅ i18n.System.getSystemLanguage() | 五端语义一致 |
Platform.isOhos 通道分支 | Dart 层(适配新增) | ✅ 已修复 | 各端一致 |
| JSON 翻译文件加载 | 纯 Dart(rootBundle) | ✅ 完整可用 | 五端一致 |
| 运行时切换(免重启) | 纯 Dart(InheritedWidget) | ✅ 完整可用 | 五端一致 |
LocaleText / 扩展 / Locales.string | 纯 Dart | ✅ 完整可用 | 五端一致 |
占位符参数 ## / ### | 纯 Dart | ✅ 完整可用 | 五端一致 |
| RTL 检测与镜像 | 纯 Dart(intl.Bidi) | ✅ 完整可用 | 五端一致 |
| 语言偏好持久化 | shared_preferences | ⚠️ 需引入 shared_preferences_ohos | Android/iOS 开箱即用 |
| 权限要求 | 不访问敏感能力 | 零权限 | 各端一致 |
更多推荐




所有评论(0)