如果你负责过高校会议室管理系统的终端屏开发,大概率遇到过同一个痛点:教学楼里既有安卓触控一体机、Windows 触摸屏,又有刚替换上来的 OpenHarmony 开发板设备,每块屏都得单独维护一套界面,视觉不统一也就罢了,改一句话欢迎语要同步改三四个工程。我去年接手的一所高校会议室管理系统,就是在这个背景下决定用 Flutter 重写全部终端界面,目标很明确:一套 Dart 代码,同时跑在 Android、OpenHarmony 和 Windows 上,真正做到跨端统一。这篇博文就围绕其中最容易被忽略、却又最复杂的“顶部欢迎区”模块,拆解我们在 Flutter × OpenHarmony 上的完整实现过程,包含工程搭建、UI 设计、跨端适配、状态联动、性能调优和踩坑记录,希望能给正在做类似跨端项目的朋友一些可复用的参考。
1. 顶部欢迎区:会议室系统的“门面”究竟在解决什么问题
1.1 会议室终端屏的真实使用场景
先还原一下使用场景。高校的会议室管理系统,通常会在每一间会议室门口或者室内放一块终端屏,平时处于待机状态,滚动显示当前时间、欢迎语、会议室名称、今日预约情况、校园通知等信息。有人走近或者预约时间临近时,屏幕要能快速切换到会议详情,显示参会人、时间段、会议主题。这个屏的核心体验不是“功能多”,而是“一眼看懂”。顶部欢迎区恰恰承担了 80% 的第一眼信息传递:访客一进门,首先看到的就是当前会议室叫什么、今天是几号、现在是几点、接下来有没有会议。
很多开发团队会低估这个模块,觉得无非是一行“欢迎光临”加一个时间插件写完后大家鼓掌通过。但实际上“顶部欢迎区”是会议室终端中交互频率最高、跨端差异最明显、对视觉一致性要求最苛刻的区域。它几乎每天都会被无数人注视,一旦在某一台 OpenHarmony 设备上字体变形、时间不刷新、欢迎语溢出屏幕,影响的不只是美观,而是整个系统的可信度。
1.2 为什么需要一个独立设计的“欢迎区”而不是整屏堆信息
会议室终端的屏幕信息量其实很大:天气、课表、待办、通知、设备状态、二维码签到,什么都想放上去。但人的视觉注意力是有限的,尤其是公共场所的屏幕,留给用户停留的时间可能只有几秒钟。顶部欢迎区的设计价值,就是把“当前所处空间”和“当前时间”这两个最高优先级的信息固定在一个明确的视觉区域内,其他信息无论怎么变,这个区域保持稳定,形成视觉锚点。
具体到我们项目,顶部欢迎区被定义为:屏幕最上方、宽度撑满、高度约 180 到 260 逻辑像素的区域。它包含三块内容:左边是校徽与楼宇名称,中间醒目的日期时间和欢迎语,右边是当前会议室预约状态指示灯。这个区域在所有页面、所有设备上都保持同样的布局和动效,而页面内容区可以自由切换。这个策略带来的直接好处是:用户在不同楼宇、不同终端之间走动时,不需要重新学习界面的信息位置。
1.3 跨端统一带来的直接收益与长期价值
从工程角度看,跨端统一最大收益是“一套代码、多端运行”。我们项目实际覆盖的设备类型有 5 种:Android 9 的会议平板、OpenHarmony 4.x 的 RK3566 开发板、OpenHarmony 5.x 的 RK3588 工控机、Windows 10 的触控一体机,以及一台用于演示的模拟器。如果沿用原生开发,至少需要 Android、OpenHarmony 和 Windows 三套技术栈,以高校信息中心的维护人力根本转不过来。引入 Flutter 之后,UI 层用 Dart 编写,平台层通过 Flutter 的适配层抽象,大部分代码可以和平台无关。
长期价值更明显。高校信息化系统有个特点:设备采购往往分多批次,不同批次硬件平台不一样,OpenHarmony 版本也有差异。跨端工程让终端屏的业务逻辑集中在同一代码库,后续换设备、升级系统,只要 Flutter 适配层支持,应用本体基本不用改。这一点在项目维护阶段的价值,远远超过开发阶段节省的成本。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 从Flutter到OpenHarmony:跨端工程搭建与依赖初始化
2.1 先分清两个“Flutter”:官方 SDK 与 OpenHarmony 适配版
这是项目启动时第一个要搞清楚的坑。普通 flutter create 创建的工程,默认只支持 Android、iOS、Web、Windows、macOS、Linux,并不直接产出 OpenHarmony 的 HAP 包。要在 OpenHarmony 设备上运行 Flutter 应用,需要基于 OpenHarmony 社区维护的 Flutter 引擎适配版本,具体做法是用 OpenHarmony 的 flutter_flutter SDK 替代官方 SDK,而不是在官方 Flutter 工程里加一个插件。
我们的做法是:克隆 OpenHarmony 的 flutter 引擎仓库和 flutter_flutter 工具仓库,编译出适配本机架构的 Flutter SDK,然后通过环境变量 FLUTTER_ROOT 指向这套 SDK,再执行常规的 flutter pub get 与 flutter build hap。注意,此时不要使用官方 flutter 命令执行项目构建,而是使用 OpenHarmony 的 flutter 工具链。编译 HAP 时,工程根目录会出现 ohos/ 目录,它等价于 Android 工程的 android/ 目录,里面是标准的 OpenHarmony 工程结构。
2.2 工程目录结构:一套 Dart 代码,多个入口壳
跨端工程的关键是“逻辑共享、入口分离”。我们采用 monorepo 结构,核心业务代码全部放在 lib/ 目录下,平台相关入口放在各自目录中:
text复制meeting_room_flutter/
├── lib/
│ ├── main.dart # 通用入口,负责初始化与启动
│ ├── app.dart # 顶层 Widget,配置主题与路由
│ ├── modules/
│ │ ├── welcome/
│ │ │ ├── welcome_banner.dart
│ │ │ ├── welcome_banner_controller.dart
│ │ │ └── clock_widget.dart
│ ├── services/
│ │ ├── room_api.dart
│ │ ├── settings_store.dart
│ │ └── time_service.dart
│ └── utils/
├── android/ # Android 平台壳工程
├── ohos/ # OpenHarmony 平台壳工程
├── windows/ # Windows 平台壳工程
└── pubspec.yaml
ohos/ 目录中关键文件是 entry/src/main/module.json5 和 build-profile.json5。前者声明应用的能力(Ability)与权限,后者管理签名与产物配置。顶部欢迎区不需要额外系统权限,但如果你要读取设备型号之类的信息,就需要在 module.json5 中声明 ohos.permission.GET_NETWORK_INFO 等权限。这个目录默认就存在,不需要手动创建。
2.3 依赖清单与 pubspec 配置:少即是多
顶部欢迎区用到的功能并不复杂:日期时间格式化、状态管理、网络请求、本地缓存。但 OpenHarmony 的插件生态不如 Android 成熟,很多 Flutter 插件虽然官方标记支持多平台,实际上 OpenHarmony 平台上没有对应实现。我们的做法是尽量精简依赖,只引入确认在 OpenHarmony 上可运行的包。
pubspec.yaml 核心依赖如下:
yaml复制dependencies:
flutter:
sdk: flutter
intl: ^0.19.0 # 日期时间格式化,纯 Dart 实现,跨端无压力
provider: ^6.1.2 # 状态管理,Flutter 标准方案
dio: ^5.4.0 # 网络请求,纯 Dart,OpenHarmony 可运行
shared_preferences: ^2.2.2 # 本地轻量存储,OpenHarmony 有适配实现
flutter_spinkit: ^5.2.0 # 加载动画,纯 Widget,无平台代码
注意,intl 可能会在 web 或某些平台引发初始化问题,但 OpenHarmony 下表现正常。shared_preferences 在 OpenHarmon
