☰
Flutter 三方库 OpenHarmony 鸿蒙适配实战:dialog_alert 纯 Dart 对话框库评估、改动与鸿蒙 PC 真机验证全流程
2026/10/27 1:44:40 网站建设 项目流程

基于 Flutter-OH 3.44.9-dev(Dart 3.12.2)在 Windows 10 22H2 上全程实测通过;真机环节在一台**鸿蒙 PC(OpenHarmony 6.1.1,API 24,arm64,2in1 形态)**上验证。文中所有源码分析、改动内容、构建输出、真机效果均为实际环境抓取,可放心对照复现。

前言

OpenHarmony × Flutter 社区资源

  • 社区主页:CPF-Flutter —— OpenHarmony Flutter 生态维护组织
  • Flutter-OH 主仓库:CPF-Flutter/flutter_flutter —— SDK 与 Engine 的 OpenHarmony 适配版本
  • 三方库适配与开发文档:OpenHarmony-Flutter —— 生态库适配清单与开发规范
  • 官方示例与开发指南:openharmony-tpc/flutter_samples —— 环境搭建指导、FAQ 与示例工程
  • 鸿蒙化适配仓库:oh-flutter/dialog_alert —— 本文 dialog_alert 的 OpenHarmony 适配版本

环境搭好之后(还没搭的看这篇 Flutter 鸿蒙环境搭建指南),下一步就是给项目引入三方库。但拿到一个库就动手改代码是大忌——先评估,再动手,能省掉大量无用功。

本文以 dialog_alert(对话框组件库)为例,完整演示从评估 → 改动 → 构建 → 真机验证的全流程,重点讲清楚一个关键判断:这个库到底需不需要写 ArkTS 原生代码?答案可能出乎你的意料。

一、库评估:拿到三方库的第一步不是改代码,是判断要不要改

1.1 dialog_alert 基本信息

dialog_alert 是一个 Flutter 对话框组件库,提供 showDialogAlert() 统一接口,支持标题、正文、确认/取消按钮及自定义按钮样式,内部通过 Platform.isIOS 自动切换 Material 和 Cupertino 两种视觉风格——整个实现完全基于 Flutter 自带的 Widget(AlertDialog、TextButton 等),不依赖任何系统原生 API。

项目内容
库名dialog_alert
pub.dev 版本0.0.3
功能显示对话框弹窗(Material / Cupertino 双风格)
主要 APIshowDialogAlert()
维护状态4 年未更新

1.2 六步评估法(来自 ohos-flutter-plugin-adaptation-necessity-check 评估流程)

拿到一个 Flutter 库,按下面六步走一遍就能得出结论:

第 1 步:目录结构检查

用 GitHub API 查看仓库根目录文件列表。dialog_alert 的根目录只有这些:

dialog_alert/ ├── lib/ ← Dart 源码 ├── example/ ← 示例工程 ├── test/ ← 单元测试 ├── gif/ ← 演示动图 ├── CHANGELOG.md ├── LICENSE ├── README.md └── pubspec.yaml

没有 android/ 目录,没有 ios/ 目录。这是第一个强信号——这个库从一开始就没有任何原生平台代码。

第 2 步:pubspec.yaml plugin 声明检查

读 pubspec.yaml 的完整内容:

name: dialog_alert description: A new Flutter package for showing native alert view in ios and native alert dialog in android. version: 0.0.3 homepage: https://github.com/mkarundas/DialogAlert environment: sdk: ">=2.15.1 <3.0.0" flutter: ">=1.17.0" dependencies: flutter: sdk: flutter dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^1.0.0 flutter:

注意三个关键点:

  • 没有 plugin: 字段——不是 Flutter 插件,是纯 Dart 包
  • 没有 platforms: 声明——没有注册任何平台的原生实现
  • dependencies 只有 flutter SDK——零三方原生依赖

虽然 description 写了"native alert view in ios and native alert dialog in android",但 pub.dev 的 description 经常名不副实——看代码不看描述。

第 3 步:MethodChannel 平台通道检查

通过 CDN 读取全部 Dart 源码(lib/ 下两个文件),搜索 MethodChannel、PlatformMessage、BinaryMessenger 等关键词。

show_dialog_alert.dart 的完整核心实现(省略 import 行):

enum ButtonActionType { action, cancel } Future<ButtonActionType?> showDialogAlert({ required BuildContext context, required String title, required String message, required String actionButtonTitle, String? cancelButtonTitle, TextStyle? actionButtonTextStyle, TextStyle? cancelButtonTextStyle, }) { return _showDialogAlert( context: context, title: title, message: message, actionButtonTitle: actionButtonTitle, cancelButtonTitle: cancelButtonTitle, actionButtonTextStyle: actionButtonTextStyle, cancelButtonTextStyle: cancelButtonTextStyle, ); }

dialog_alert_button.dart 的完整实现:

class DialogAlertButton extends StatelessWidget { const DialogAlertButton({ Key? key, required this.onPressed, required this.title, this.isDestructiveAction = false, this.isDefaultAction = false, this.textStyle, }) : super(key: key); final VoidCallback onPressed; final String title; final bool isDestructiveAction; final bool isDefaultAction; final TextStyle? textStyle; @override Widget build(BuildContext context) { return !Platform.isIOS ? TextButton( onPressed: onPressed, child: Text( title, style: textStyle, ), ) : CupertinoDialogAction( isDestructiveAction: isDestructiveAction, isDefaultAction: isDefaultAction, onPressed: onPressed, child: Text( title, style: textStyle, ), ); } }

零 MethodChannel,零平台通道调用。所有 UI 完全由 Flutter Widget(AlertDialog、TextButton、CupertinoAlertDialog、CupertinoDialogAction)实现。

第 4 步:Platform.isIOS 平台判断检查

两个文件中都有 Platform.isIOS 判断,用于切换 Material / Cupertino 风格。这个判断在 OpenHarmony 上的行为后面第四章详细分析。

第 5 步:依赖递归检查

唯一依赖是 flutter SDK 本身,无递归依赖链风险。

第 6 步:综合判断

评估维度结果
原生平台代码(android/、ios/)无
MethodChannel / 平台通道无
pubspec plugin 声明无
三方原生依赖无
结论纯 Dart 实现,无需原生适配,可直接用于 OpenHarmony

关键提醒:pub.dev 的 platforms 字段标注了 Flutter、Android、iOS、Windows 等平台——这个字段不可靠。纯 Dart 包会被 pub.dev 自动标注为全平台支持,不代表它有原生实现。判断的唯一标准是看源码有没有 MethodChannel 和原生目录。


二、适配流程:两处 pubspec 改动 + 一个 ohos 宿主工程

评估结论是"纯 Dart 无需原生适配"后,实际改动非常轻量。

2.1 克隆仓库到本地

原库托管在 GitHub,国内网络直连不稳定,使用 ghproxy 镜像加速:

cd D:\Flutters git clone https://ghproxy.net/https://github.com/mkarundas/DialogAlert.git dialog_alert

如果你的网络能直连 GitHub,直接用原始地址 git clone https://github.com/mkarundas/DialogAlert.git dialog_alert 即可。

2.2 修改 Dart SDK 版本约束(唯一的代码改动)

这是整个适配过程中唯一需要改代码的地方。

问题:原库 pubspec.yaml 的 SDK 约束是 >=2.15.1 ❤️.0.0,上限锁死在 Dart 2。而 Flutter-OH 3.44.9 搭载的是 Dart 3.12.2,flutter pub get 直接报版本冲突:

Because dialog_alert requires SDK version >=2.15.1 <3.0.0, version solving failed.

修法:把上限从 ❤️.0.0 放宽到 <4.0.0。

修改前(pubspec.yaml 第 6~8 行):

environment: sdk: ">=2.15.1 <3.0.0" flutter: ">=1.17.0"

修改后:

environment: sdk: ">=2.15.1 <4.0.0" flutter: ">=1.17.0"

example 工程的 pubspec.yaml 同步修改(SDK 约束放宽 + 主包依赖改为本地路径引用)。

修改前:

environment: sdk: ">=2.15.1 <3.0.0" dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.2 dialog_alert: ^0.0.2

修改后:

environment: sdk: ">=2.15.1 <4.0.0" dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.2 dialog_alert: path: ../

path: …/ 让 example 直接引用本地修改后的主包,而不是从 pub.dev 拉原版——这样后面的真机验证测的就是我们改过的版本。

为什么原库 4 年没更新?dialog_alert 最后一次发布是 2021 年,当时 Dart 3 还没发布,作者写 ❤️.0.0 完全合理。只是库停更后,新环境(Dart 3)和旧约束之间出现了不兼容。放宽到 <4.0.0 是社区公认的兼容修法,向下兼容 Dart 2,向上兼容 Dart 3。

2.3 创建 OpenHarmony 宿主工程

example 工程原本只有 android/ 和 ios/ 宿主,需要补上 ohos/:

cd D:\Flutters\dialog_alert\example flutter create --platforms=ohos .

这条命令在 example/ 下生成 ohos/ 目录(约 39 个文件),结构如下:

example/ohos/ ├── entry/src/main/ │ ├── module.json5 ← 设备类型声明(下一步要改) │ ├── ets/entryability/ ← 应用入口 Ability │ └── resources/ ← 资源文件 ├── build-profile.json5 ← 构建配置(签名后会自动写入证书路径) ├── hvigorfile.js ← hvigor 构建脚本 └── oh-package.json5 ← ohpm 包配置

2.4 补全 deviceTypes(鸿蒙 PC 必改项)

flutter create 生成的 module.json5 里,deviceTypes 只有 phone。如果你的目标设备是鸿蒙 PC(2in1 形态)或平板(tablet),必须补全,否则 DevEco Studio 运行时会报设备类型不匹配:

Error Message: The type of target device does not match the device type configured by module: entry. Required device type:2in1, current module device type:phone

修改 example/ohos/entry/src/main/module.json5:

{ "module": { "name": "entry", "type": "entry", "deviceTypes": [ "phone", "tablet", "2in1" ], // ... 其余配置保持不变 } }

经验值:凡是 Flutter-OH 工程(包括三方库适配的 example),deviceTypes 建议 phone、tablet、2in1 三态全声明,一步到位兼容所有鸿蒙设备形态。


三、构建与真机验证

3.1 DevEco Studio 配置调试签名

真机运行 HAP 必须有签名。配置一次即可,后续命令行构建不再需要打开 DevEco。

操作步骤(中文版 DevEco Studio 26 实测菜单路径):

  1. DevEco Studio →「文件」→「打开」→ 选择D:\Flutters\dialog_alert\example\ohos(注意是 ohos 子目录,不是 example 根目录,选错找不到签名入口)
  2. 等右下角工程同步完成
  3. 「文件」→「项目结构」→ 左侧「签名配置」→ 勾选「自动生成签名」
  4. 弹出华为账号登录框,登录后证书自动填充,点「确定」

签名信息写入 example/ohos/build-profile.json5。

3.2 运行与构建

在 example 目录下执行:

cd D:\Flutters\dialog_alert\example flutter run

只连一台设备时不用 -d 参数。hvigor 编译(实测约 38 秒)完成后,应用自动安装到设备并启动。

也可以直接在 DevEco Studio 里点运行按钮,效果一样。DevEco 方式走 IDE 内部的 JDK 构建,不会受系统 JAVA_HOME 版本影响。

3.3 真机效果验证

example 的 main.dart 提供了三个按钮,逐个点击验证:

按钮 1:Simple Alert Dialog

showDialogAlert( context: context, title: 'Success', message: 'You have successfully updated your profile.', actionButtonTitle: 'OK', );

预期效果:弹出 Material 风格对话框,标题"Success",正文提示,底部一个"OK"按钮。

按钮 2:Alert Dialog with Cancel Button

final result = await showDialogAlert( context: context, title: 'Message', message: 'Do you want to upload your profile picture?', actionButtonTitle: 'Upload', cancelButtonTitle: 'Cancel', );

预期效果:弹出带"Upload"和"Cancel"两个按钮的对话框。返回值为 ButtonActionType.action 或 ButtonActionType.cancel。

按钮 3:Custom Button Title Text Style

final result = await showDialogAlert( context: context, title: 'Success', message: 'You have successfully uploaded', actionButtonTitle: 'Submit', cancelButtonTitle: 'Cancel', actionButtonTextStyle: const TextStyle( color: Colors.green, ), cancelButtonTextStyle: const TextStyle( color: Colors.pink, ), );

预期效果:弹出对话框,"Submit"按钮绿色,"Cancel"按钮粉色——验证 TextStyle 自定义参数也能正常传递。

实测结果:三个按钮全部正常弹窗,所有 API 参数工作正常。

验证状态汇总:

验证项状态说明
依赖解析(flutter pub get)✅ 通过Dart 3.12.2 下 SDK 约束冲突已修复
hvigor 编译(flutter build hap)✅ 通过实测约 38 秒完成
真机运行(三个按钮弹窗)✅ 通过Material 风格,全部 API 工作正常

四、源码深度分析:Platform.isIOS 在鸿蒙上的行为

4.1 关键判断逻辑

库内所有平台区分逻辑集中在一个函数里(show_dialog_alert.dart 第 58~73 行):

Future<ButtonActionType?> _showDialogAlertWidget( BuildContext context, String title, String message, List<Widget> actions) { if (!Platform.isIOS) { return showDialog( context: context, builder: (context) => AlertDialog( title: Text(title), content: Text(message), actions: actions)); } return showCupertinoDialog( context: context, builder: (context) => CupertinoAlertDialog( title: Text(title), content: Text(message), actions: actions, )); }

逻辑很简单:不是 iOS 就走 Material 风格(showDialog + AlertDialog),是 iOS 就走 Cupertino 风格(showCupertinoDialog + CupertinoAlertDialog)。

4.2 OpenHarmony 上的实际走向

dart:io 的 Platform.isIOS 在 OpenHarmony 上恒为 false(鸿蒙不是 iOS 设备),所以代码始终走 Material 分支。

这意味着:

  • showDialog() 弹出 Material 风格对话框 → ✅ 正常工作
  • AlertDialog 渲染标题、正文、按钮 → ✅ 正常工作
  • TextButton 渲染按钮(支持 TextStyle 自定义) → ✅ 正常工作
  • Navigator.pop() 返回 ButtonActionType 枚举值 → ✅ 正常工作

Cupertino 风格(CupertinoAlertDialog)在鸿蒙上永远不会触发——这不是缺陷,而是库的设计行为。Android 上也是同样的表现,鸿蒙与 Android 一致。

4.3 按钮侧的同一模式

DialogAlertButton 的 build 方法也是同样的判断:

@override Widget build(BuildContext context) { return !Platform.isIOS ? TextButton( onPressed: onPressed, child: Text( title, style: textStyle, ), ) : CupertinoDialogAction( isDestructiveAction: isDestructiveAction, isDefaultAction: isDefaultAction, onPressed: onPressed, child: Text( title, style: textStyle, ), ); }

鸿蒙上走 TextButton 分支,与 Android 行为完全一致。

4.4 为什么纯 Dart 库能直接跨平台

Flutter 的核心设计理念是"一次编写,多端运行"。Material 和 Cupertino 组件都是Flutter 框架自带的纯 Widget 实现,渲染由 Flutter Engine 的 Skia/Impeller 图形引擎完成,不依赖任何操作系统原生 UI 控件。

所以:

  • AlertDialog 不是调用系统的对话框 API,而是 Flutter 自己画的
  • TextButton 不是系统的按钮控件,而是 Flutter 自己渲染的
  • 只要 Flutter Engine 能在某个平台上跑(OpenHarmony 可以),这些 Widget 就能正常工作

这就是纯 Dart 库无需原生适配的根本原因——它从头到尾都没碰过原生代码。


常见问题 FAQ

Q1:拿到一个 Flutter 库,怎么快速判断它需不需要原生适配?

看 pubspec.yaml 有没有 plugin: platforms: 声明。下面是一个需要原生适配的插件库 pubspec(对比 dialog_alert 的纯 Dart 包 pubspec):

# 需要原生适配的插件库(如 toast、share_plus 等) flutter: plugin: platforms: android: pluginClass: ToastPlugin ios: pluginClass: ToastPlugin ohos: pluginClass: ToastPlugin

dialog_alert 的 pubspec 里没有 plugin: 字段——说明它是纯 Dart 包,不需要写任何原生代码。pub.dev 的 platforms 标签不可靠,纯 Dart 包会被自动标注为全平台支持,判断的唯一标准是看 pubspec 有没有 plugin 声明。

Q2:dialog_alert 的 description 写了"native alert view in ios and native alert dialog in android",为什么实际没有原生代码?

看源码就知道——showDialogAlert 内部用的是 Flutter 自带的 Widget,不是系统原生 API:

// show_dialog_alert.dart 第 58~73 行(真实源码) if (!Platform.isIOS) { return showDialog( // Flutter 框架方法 context: context, builder: (context) => AlertDialog( // Flutter 框架 Widget title: Text(title), content: Text(message), actions: actions)); } return showCupertinoDialog( // Flutter 框架方法 context: context, builder: (context) => CupertinoAlertDialog( // Flutter 框架 Widget title: Text(title), content: Text(message), actions: actions, ));

showDialog、AlertDialog、showCupertinoDialog、CupertinoAlertDialog 全部是 Flutter 框架自带的纯 Widget 实现,渲染由 Flutter Engine 完成,不依赖任何操作系统原生 UI 控件。description 里的"native"是宣传用语,名不副实。

Q3:鸿蒙上弹窗是 Material 风格而不是 Cupertino 风格,算适配缺陷吗?

不算。库内通过 Platform.isIOS 区分风格:

// dialog_alert_button.dart 第 23~39 行(真实源码) return !Platform.isIOS ? TextButton(...) // Material 风格 → 鸿蒙走这里 : CupertinoDialogAction(...); // Cupertino 风格 → 仅 iOS

鸿蒙上 Platform.isIOS 恒为 false,始终走 TextButton 分支——这和 Android 上的行为完全一致,是库的设计行为,不是适配缺陷。

Q4:如果想练完整的原生适配流程(Kotlin → ArkTS 翻译),应该选什么库?

选 pubspec.yaml 里有 plugin: platforms: 声明且有 MethodChannel 调用的库。比如一个典型的需要完整适配的插件:

# 需要完整原生适配的插件库 pubspec.yaml flutter: plugin: platforms: android: pluginClass: VibrationPlugin ohos: pluginClass: VibrationPlugin # 需要你在 ArkTS 中实现这个类

对应的 Dart 侧会有 MethodChannel 调用:

// Dart 侧通过 MethodChannel 调用原生能力 static const _channel = MethodChannel('com.example/vibration'); Future<void> vibrate() => _channel.invokeMethod('vibrate');

这类库才需要走完整五阶段:生成 ohos 骨架 → 把 Kotlin/Java 翻译成 ArkTS → 注册 pluginClass → 构建 HAR → 真机验证。典型代表:toast(系统通知)、vibration(振动)、share_plus(系统分享)。

Q5:SDK 约束放宽到 <4.0.0 会不会影响 Dart 2 的兼容性?

不会。看修改前后对比:

# 修改前:只兼容 Dart 2 environment: sdk: ">=2.15.1 <3.0.0" # 只接受 2.15.1 ~ 2.x.x # 修改后:同时兼容 Dart 2 和 Dart 3 environment: sdk: ">=2.15.1 <4.0.0" # 接受 2.15.1 ~ 3.x.x

下限 >=2.15.1 没变,Dart 2 的老项目照样能用;上限从 ❤️.0.0 放宽到 <4.0.0,Dart 3 环境也能解析。这是社区对老库停更后出现版本冲突的标准修法。

Q6:真机运行必须用命令行 flutter run 吗?

不是,两种方式都可以:

# 方式一:命令行(支持热重载) cd D:\Flutters\dialog_alert\example flutter run # 按 r 热重载,按 R 热重启,按 q 退出 # 方式二:DevEco Studio 点运行按钮 # 文件 → 打开 → example/ohos → 点运行按钮

DevEco 方式走 IDE 内部的 JDK 构建,不会受系统 JAVA_HOME 版本影响。flutter run 的优势是支持热重载(按 r 秒级刷新),适合开发阶段频繁调试;DevEco 方式适合不习惯命令行的用户。

Q7:deviceTypes 必须三个都写吗?只写 phone 行不行?

只写 phone 在手机上能跑,但换设备就报错:

// ❌ 只声明 phone → 鸿蒙 PC(2in1)和平板上报错 "deviceTypes": ["phone"], // Error: Required device type:2in1, current module device type:phone // ✅ 三态全声明 → 一次兼容所有鸿蒙设备形态 "deviceTypes": [ "phone", // 手机 "tablet", // 平板 "2in1" // 鸿蒙 PC ],

建议所有 Flutter-OH 工程都写全三态,避免切换设备时再改。


总结

本文完整记录了 dialog_alert 库从评估到鸿蒙 PC 真机验证的全流程:先通过六步评估法确认它是纯 Dart 实现(无原生目录、无 MethodChannel、无 plugin 声明),然后只做了两处 SDK 约束放宽(pubspec.yaml 的 ❤️.0.0 改为 <4.0.0)+ 一行本地路径依赖(path: …/)+ 一个 flutter create 生成的 ohos 宿主 + 一行 deviceTypes 补全,Dart 层源码零改动,就在鸿蒙 PC 真机上跑通了全部三个对话框弹窗。核心经验:拿到库先花 5 分钟评估类型,纯 Dart 库根本不需要写 ArkTS 代码——动手前查一眼源码,能省掉几小时的无用功。动手前也建议先查一眼 Flutter OH 三方库适配列表,很多热门库已有人适配过,别重复造轮子。

参考资料

  • CPF-Flutter 社区主页
  • CPF-Flutter/flutter_flutter(Flutter-OH 主仓库)
  • oh-flutter/dialog_alert(鸿蒙化适配仓库)
  • Flutter OH 三方库适配列表
  • dialog_alert 原库源码
  • Flutter 鸿蒙环境搭建指南
  • Flutter OH 官方示例与 FAQ

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询