前言

Flutter是Google开发的开源UI工具包,支持用一套代码构建iOSAndroidWebWindowsmacOSLinux六大平台应用,实现"一次编写,多处运行"。

OpenHarmony是由开放原子开源基金会运营的分布式操作系统,为全场景智能设备提供统一底座,具有多设备支持、模块化设计、分布式能力和开源开放等特性。

Flutter for OpenHarmony技术方案使开发者能够:

  1. 复用Flutter现有代码(Skia渲染引擎、热重载、丰富组件库)
  2. 快速构建符合OpenHarmony规范的UI
  3. 降低多端开发成本
  4. 利用Dart生态插件资源加速生态建设

先看效果

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/1d10fc5f05344d73af546ab112ae2ea4.gif

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

在这里插入图片描述

演示页面与组件使用指南

本项目当前的核心演示是一个“仪表盘 + 进度环”的视觉与交互示例:上半部分展示半圆仪表盘(系统负载),右侧展示圆形进度环(同步进度);下方提供滑块与快捷预设,用于实时观察数值变化、渐变高亮与发光效果在动画过程中的表现。整体 UI 基于霓虹渐变背景与玻璃拟态卡片风格,适合用来快速搭建“科技感数据面板”的基础视觉体系。

目录


入口与演示目标

应用入口在 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

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐