Flutter for OpenHarmony 实战:仪表盘与进度环形图
是Google开发的开源UI工具包,支持用一套代码构建和六大平台应用,实现"一次编写,多处运行"。是由开放原子开源基金会运营的分布式操作系统,为全场景智能设备提供统一底座,具有多设备支持、模块化设计、分布式能力和开源开放等特性。
前言
Flutter是Google开发的开源UI工具包,支持用一套代码构建iOS、Android、Web、Windows、macOS和Linux六大平台应用,实现"一次编写,多处运行"。
OpenHarmony是由开放原子开源基金会运营的分布式操作系统,为全场景智能设备提供统一底座,具有多设备支持、模块化设计、分布式能力和开源开放等特性。
Flutter for OpenHarmony技术方案使开发者能够:
- 复用Flutter现有代码(Skia渲染引擎、热重载、丰富组件库)
- 快速构建符合OpenHarmony规范的UI
- 降低多端开发成本
- 利用Dart生态插件资源加速生态建设
先看效果

在鸿蒙真机 上模拟器上成功运行后的效果

演示页面与组件使用指南
本项目当前的核心演示是一个“仪表盘 + 进度环”的视觉与交互示例:上半部分展示半圆仪表盘(系统负载),右侧展示圆形进度环(同步进度);下方提供滑块与快捷预设,用于实时观察数值变化、渐变高亮与发光效果在动画过程中的表现。整体 UI 基于霓虹渐变背景与玻璃拟态卡片风格,适合用来快速搭建“科技感数据面板”的基础视觉体系。
目录
- 入口与演示目标
- 页面:GaugeRingDemoPage
- 交互与动画机制
- NeonBackground(霓虹背景)
- GlassCard(玻璃卡片容器)
- NeonGauge(半圆仪表盘)
- NeonProgressRing(进度环)
- 页面内交互部件
- HarmonyOS 接入与承载
- 扩展与二次开发建议
入口与演示目标
应用入口在 lib/main.dart,启动后直接进入 GaugeRingDemoPage。主题层面统一使用暗色方案,并把 scaffoldBackgroundColor 设为透明,让背景组件可以贯穿整个页面,避免出现“背景被 Scaffold 覆盖一层纯色”的割裂感。
演示目标可以概括为三点:
1)同一套视觉语言下,如何把“背景氛围”和“信息承载”分离:背景负责气质,卡片负责信息可读性;2)用尽量少的状态管理代码,实现顺滑的数值过渡动画;3)通过可调参数(渐变、线宽、尺寸、透明度),快速产出不同密度的面板布局,而不是把样式写死在页面里。
页面:GaugeRingDemoPage
文件位置:lib/pages/gauge_ring_demo_page.dart。
页面结构采用 CustomScrollView + Sliver,便于在同一滚动体系里组合多个区域:头部标题与随机按钮、主要展示卡片(仪表盘 + 进度环 + 滑块)、以及底部快捷预设卡片组。虽然当前演示内容不多,但这种结构适合后续扩展更多卡片(例如新增温度、内存、网络等指标)而不需要重写布局体系。
页面的关键组合点是“背景 + 安全区 + 滚动容器”的层次:
Scaffold(
backgroundColor: Colors.transparent,
body: NeonBackground(
child: SafeArea(
child: CustomScrollView(
slivers: [/* ... */],
),
),
),
)
这个组合能确保:背景始终铺满;内容不被刘海/状态栏遮挡;内容区可以自然滚动并保持统一的边距体系。
交互与动画机制
演示页面的动画核心是一个 AnimationController,配合两个 Animation<double>(仪表盘数值与进度环数值)。当用户拖动滑块或点击快捷预设时,不直接瞬间改 UI,而是调用 _animateTo:以“当前动画值”为起点,向新目标值过渡,并统一使用 easeOutCubic 曲线让末端收得更自然。
这种写法的好处是:无论变化来自滑块连续拖动、随机按钮突变、还是预设卡片跳变,动画行为都一致;同时它避免了“开始值被重置为旧目标”导致的跳帧,视觉上更连贯。为了让页面构建保持清晰,数据计算(目标值、随机范围)在页面 state 内完成,绘制细节沉到各自的自绘组件里,互相边界明确。
NeonBackground(霓虹背景)
文件位置:lib/widgets/neon_background.dart。
NeonBackground 的职责是提供统一的“氛围层”:底色渐变 + 三块径向光晕 + 斜向网格线 + 轻微暗角。它不关心页面内容是什么,只包裹 child。由于背景是纯绘制(CustomPainter)且 shouldRepaint 返回 false,这层基本不会引入额外的重绘压力,适合长期作为页面底座使用。
使用方式很直接:
NeonBackground(
child: /* 页面内容 */,
)
二次开发时建议优先把“光晕位置、透明度、网格密度”做成可配置参数,这样同一套背景能服务更多页面:信息密度高的页面可以降低网格对比度,数据大屏可以增强光晕范围来提高科技感,但都不需要复制一份 painter。
GlassCard(玻璃卡片容器)
文件位置:lib/widgets/glass_card.dart。
GlassCard 是信息承载层的基础构件:用 BackdropFilter 做模糊,叠加半透明渐变与细边框,既能把背景压下去提升可读性,又不会变成厚重的纯色块。它把常用的 padding 与圆角作为参数暴露出来,页面可以按区域密度微调,而不需要每次手写一套装饰。
典型用法:
GlassCard(
child: Column(
children: [/* 内容 */],
),
)
如果后续要在卡片内放更多交互(按钮、水波纹、列表),建议在 GlassCard 内部内容区域再补一层 Material(由页面侧决定),以保证 Ink 系列交互效果稳定,而不是让装饰层影响触摸反馈。
NeonGauge(半圆仪表盘)
文件位置:lib/widgets/neon_gauge.dart。
NeonGauge 通过 CustomPainter 绘制半圆轨道与进度弧,使用 SweepGradient 作为进度弧的着色,并辅以模糊发光层增强高亮。它的接口重点围绕“可复用的语义参数”设计:value/min/max 决定数据范围;height/strokeWidth 决定占位与线条厚度;trackColor/gradient/glowColor 决定风格;label/footer 用于补充文案与徽标信息。
在页面中使用:
NeonGauge(
value: gaugeV,
min: 0,
max: 100,
label: '系统负载',
footer: _TinyBadge(text: _loadLabel(gaugeV)),
)
开发时建议把“绘制性能”当作第一约束:仪表盘属于高关注组件,动画期间重绘频繁。当前实现已经用 RepaintBoundary 做了隔离;若未来增加更多装饰(例如刻度数字、渐变底座),优先保证绘制元素数量可控,避免在每帧里做复杂路径运算。
NeonProgressRing(进度环)
文件位置:lib/widgets/neon_progress_ring.dart。
NeonProgressRing 绘制完整圆形轨道与按比例增长的进度弧,并在弧线头部增加高亮点,让“进度方向”更明确。它把 size/strokeWidth 作为布局核心参数,使得在不同卡片密度下可以快速缩放;center 支持自定义中心内容,既能显示百分比,也能放两行说明文字或小图标,从而兼容不同场景(同步、完成度、占用率等)。
在演示页中使用自定义 center:
NeonProgressRing(
value: ringV,
size: 148,
strokeWidth: 16,
center: _RingCenter(
primary: '${(ringV * 100).round()}%',
secondary: '同步进度',
),
)
二次开发建议保持“进度环语义单一”:它负责把 0~1 的数值可视化,不直接承担业务含义。业务侧通过 center 文案表达语义即可,这样同一个环能复用于不同模块。
页面内交互部件
演示页内还有几类小部件用于呈现完整体验:
_GlowButton:头部“随机”按钮,用半透明底 + 边框 + 外发光阴影体现可点击性。它是一个很好的按钮样式基座,后续可以抽到 widgets 目录复用。_Controls与_SliderRow:两条滑块联动两类数值,右侧胶囊数值框使用 tabularFigures,避免数字宽度变化导致抖动。_QuickActions与_PresetCard:三张预设卡片快速切换到不同风格的数值组合,便于演示“同一套视觉组件在不同数据分布下的表现”。
这些部件的共同点是:把交互入口尽量做得直观,让用户不看说明也能理解“拖动能变、点击能切、变化有动画”。在后续扩展更多指标时,可以继续沿用“一个展示卡片 + 一组可调控件 + 一组预设”的结构,演示效果会更完整。
HarmonyOS 接入与承载
HarmonyOS 侧入口位于 ohos/entry/src/main/ets/entryability/EntryAbility.ets,通过 FlutterAbility 启动 Flutter 引擎并注册插件。页面承载在 ohos/entry/src/main/ets/pages/Index.ets,用 FlutterPage({ viewId }) 显示 Flutter 内容,同时拦截返回键事件向上层派发。
这层接入代码的意义在于:演示项目不仅能在 Flutter 环境下跑通,也给出了在 HarmonyOS 工程内嵌 Flutter 页面时的最小可用骨架。后续如果增加更多原生侧能力(路由、生命周期、平台通道),建议在该入口层集中管理,避免把平台逻辑散落到具体组件里。
扩展与二次开发建议
1)新增指标:以 GlassCard 为容器,新增一行或一列展示组件(例如第二个进度环或新的仪表盘),并把页面状态扩展为更多 target 值,仍然通过同一个 controller 统一驱动动画,保持手感一致。
2)统一样式参数:把渐变、glow 透明度、线宽、圆角等抽到一个轻量的样式对象或常量文件,避免页面与组件之间出现“同色不同值”的漂移。
3)复用小部件:当 _GlowButton、_PresetCard 在多个页面出现时再抽取到 lib/widgets/,抽取后只暴露语义参数(文本、icon、onTap),样式内部自洽,调用方不需要传一堆颜色。
4)性能与可读性:自绘组件尽量维持 RepaintBoundary 的隔离边界;文本区域优先保证对比度与字号层级,其次再加装饰。霓虹风格最容易踩的坑是“好看但看不清”,因此可读性永远排在第一位。
欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net
更多推荐



所有评论(0)