Flutter三方库适配OpenHarmony【harmony_ui】沉浸光感材质与 UI Design Kit 增强组件实战

前言

如果说基础组件决定了 App"能不能用",那么沉浸光感和 UI Design Kit 决定了它"像不像鸿蒙"。这两个特性是 HarmonyOS 设计语言里最有辨识度、也最难还原的部分:一层会呼吸的毛玻璃悬浮在内容之上,彩色光晕跟随指尖漫溢,点光源把卡片边缘照亮——在原生 ArkUI 里它们是系统能力,在 Flutter 里则需要自己画出来。

harmony_ui 用纯 Dart 自绘把这些能力完整实现了出来:OhosLightMaterial 提供 ULTRA_THIN … ULTRA_THICK 五档毛玻璃材质,OhosLightSource / OhosIlluminated 实现点光源,再叠加 OhosPressShadow 按压阴影、OhosSideBar 侧边栏、OhosListItem 横滑列表、常驻通知、动态模糊标题栏、可展开操作栏等 9 项 UI Design Kit 增强能力。

本系列按官方控件的六大类别各写一篇,本篇是第 7 篇(收官篇),专门讲六大类别之外的"增强类"能力。全部内容都可以在 OpenHarmony 模拟器上运行验证(API 26,1280×2832),截图全部来自模拟器实机。

一、沉浸光感:HarmonyOS 的视觉名片

1.1 设计原理

官方沉浸光感规范把"玻璃"描述为多层结构的合成结果,而不是一张磨砂贴图:

  1. 模糊背板:对下方内容做高斯模糊,强度分五档;
  2. 表面填充:半透明底色,保证模糊内容之上的可读性;
  3. 光池(glow pools):彩色光晕在介质内漫溢,位置可跟随交互(选中项、按压点);
  4. 高光:镜面高光随动画扫掠,边缘绘制 rim 亮边与发丝高光;
  5. 阴影与漫射:背板投影制造悬浮感,可选的背景放大折射带来"玻璃厚度"。

OhosLightMaterial 按同样的层次自绘合成,并且每一档都有独立的参数集(表面填充/光池/高光/阴影/漫射),保证 ULTRA_THIN 的"薄纱感"和 ULTRA_THICK 的"厚玻璃感"差异明显。

1.2 五档材质

档位sigma定位官方典型场景harmony_ui 组件默认值
ultraThin8最薄,几乎透明顶部悬浮标题栏OhosAppBar(lightMaterial: true)
thin16薄,内容略透出悬浮底部页签OhosNavigationBar(type: float, lightMaterial: true)
regular24中等中等尺寸悬浮层-
thick32厚,内容明显柔化大尺寸弹层-
ultraThick40最厚,接近实体半模态 / 全屏弹层OhosBottomSheet

各档位在模拟器上的实际效果:

沉浸光感五档材质(THIN / THICK,实机)

沉浸光感:不同档位模糊背板、光池与高光在内容之上的悬浮层次对比

二、OhosLightMaterial 深入使用

2.1 基础用法

把任意子树包进 OhosLightMaterial 就获得光感材质,level 控制档位,gradientFade 控制渐变方向(标题栏用顶部淡出、底部页签用底部淡出):

// 顶部悬浮:ULTRA_THIN + 顶部渐变模糊
OhosLightMaterial(
  level: OhosLightMaterialLevel.ultraThin,
  gradientFade: OhosLightFade.top,
  child: OhosAppBar(lightMaterial: true, title: const Text('标题')),
)

// 底部悬浮:THIN + 光池跟随选中项
OhosNavigationBar(
  type: OhosNavigationBarType.float,
  lightMaterial: true,
  glow: true,
  destinations: destinations,
)

// 半模态 / 大弹层:ULTRA_THICK + 光感漫射
OhosLightMaterial(
  level: OhosLightMaterialLevel.ultraThick,
  effectTuning: const OhosLightEffectTuning(scatterScale: 0.6),
  child: panel,
)

2.2 效果调参

OhosLightEffectTuning 提供 blur / surface / glow / shadow / specular / scatter 六项倍率,可以模拟官方"强 / 均衡 / 弱"三档氛围,也可以做品牌化定制:

const OhosLightEffectTuning(
  blurScale: 1.0,        // 模糊强度倍率
  surfaceScale: 1.0,     // 表面填充倍率
  glowScale: 1.2,        // 光池增强
  shadowScale: 0.8,      // 投影减弱
  specularScale: 1.0,    // 高光倍率
  scatterScale: 0.0,     // 光感漫射(默认关闭以省性能)
)
  • 性能注意:scatterScale(光感漫射)需要额外绘制背景放大折射层,默认关闭;长列表滚动场景中建议保持关闭,仅在大弹层中开启;
  • 深色模式:材质参数与主题无关,但光池配色会随明暗主题调整,深色下更通透;
  • 技术参考(MIT):材质分层思路借鉴自 harmony_immersive_glow_tabbar 与 liquid_glass_widgets。由于后者要求 Flutter ≥ 3.41.0 而鸿蒙社区分叉是 3.35.x,无法直接依赖,harmony_ui 采用同思路的自绘实现。

提示:OhosLightMaterial 本身与 OhosAppBar / OhosNavigationBar / OhosBottomSheet 三个组件是"可组合"关系——组件内置 lightMaterial: true 开关,也可以脱离组件单独包裹任意内容,两层用法自由切换。

三、标题栏与底部页签的光感

3.1 动态模糊标题栏

OhosAppBar 的 scrollEffect 是 UI Design Kit「动态模糊标题栏」能力的实现:内容穿透标题栏滚动,滚动进入 blurEffectiveStartOffset ~ blurEffectiveEndOffset 区间后,模糊背板按进度淡入。三种效果类型:

OhosAppBar(
  backgroundColor: Colors.transparent,   // 初始透明,内容穿透
  title: const Text('标题'),
  scrollController: _scroller,
  scrollEffect: const OhosAppBarScrollEffectOptions(
    effect: OhosAppBarScrollEffectType.commonBlur, // common/transition/gradient
    blurEffectiveStartOffset: 0,     // 开始产生模糊的偏移
    blurEffectiveEndOffset: 60,      // 模糊达到满值的偏移
    blurSigma: 10,                   // 模糊强度
  ),
)
效果类型行为适用场景
commonBlur达到区间后常显模糊背板常规内容流页面
transitionBlur模糊随滚动进度连续变化沉浸式首屏
gradientBlur模糊 + 渐变蒙层叠加大图头部页面

动态模糊标题栏实机效果(滚动后标题栏背板淡入):

动态模糊标题栏(滚动后,实机)

动态模糊标题栏:内容穿透滚动,进入阈值区间后 commonBlur 背板淡入

3.2 悬浮底部页签光池

悬浮底部页签打开 glow: true 后,OhosLightPalette.glowColors 定义的彩色光晕会跟随选中项位置移动,按压时在指尖位置出现光晕——这是官方"光跟随交互"的核心观感:

OhosNavigationBar(
  type: OhosNavigationBarType.float,
  lightMaterial: true,
  glow: true,
  currentIndex: _index,
  onDestinationSelected: (int i) => setState(() => _index = i),
  destinations: const [
    OhosNavigationDestination(icon: Icon(Icons.home_filled), label: '首页'),
    OhosNavigationDestination(icon: Icon(Icons.square_grid_2x2), label: '组件'),
    OhosNavigationDestination(icon: Icon(Icons.person_filled), label: '我的'),
  ],
)
  • 光池移动有动画过渡,切换页签时光晕平滑滑动而非瞬移;
  • 按压光晕在抬手后自动淡出,与 OhosGeometry.spring 90ms 曲线一致;
  • 平铺式页签(非悬浮)同样支持 lightMaterial: true,只是无悬浮投影。

四、半模态面板与光感漫射

showOhosBottomSheet 默认使用 ULTRA_THICK 材质,是光感"最厚"的应用场景:

await showOhosBottomSheet(
  context: context,
  title: '分享到',
  content: SizedBox(
    height: 200,
    child: Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: const [
        // 分享入口图标
      ],
    ),
  ),
);

需要更"通透"或更"厚重"时,可以脱离便捷函数,直接用 OhosLightMaterial 包自己的弹层,并通过 effectTuning 调参:

// 更通透:模糊与光池都减弱
OhosLightMaterial(
  level: OhosLightMaterialLevel.thick,
  effectTuning: const OhosLightEffectTuning(
    blurScale: 0.8,
    glowScale: 0.6,
  ),
  child: mySheet,
)

// 更厚重:开启光感漫射,玻璃"厚度"感更强
OhosLightMaterial(
  level: OhosLightMaterialLevel.ultraThick,
  effectTuning: const OhosLightEffectTuning(scatterScale: 0.6),
  child: mySheet,
)

提示:半模态是 scatterScale 最值得开启的场景——弹层面积大、不随滚动高频重绘,漫射的额外开销可忽略,而"玻璃厚度"收益最明显。

五、UI Design Kit:点光源与按压阴影

5.1 点光源

点光源(PointLight)是 UI Design Kit 中"光"主题的另一个落点:一个发光源朝受光面投射环境光,受光边缘被照亮、表面出现"光晕 + 光柱"。原生 ArkUI 的 hdsEffect.PointLight 在模拟器上不支持(官方文档明确),harmony_ui 用自绘合成达到同样的视觉层次。

两种角色分工明确:

  • OhosLightSource:发光源,通常是卡片里的按钮、旋钮等交互控件;
  • OhosIlluminated:受光面,被照亮的容器(卡片、面板)。

受光类型共 5 种(对应官方 PointLightIlluminatedType):

类型效果
none不受光(关闭)
border仅受光侧边缘被照亮
content表面出现柔和光池
borderContent亮边 + 光池同时出现
defaultFeatheringBorder更宽的羽化亮边
OhosIlluminated(
  illuminatedType: OhosPointLightIlluminatedType.borderContent,
  lightAlignment: const Alignment(0.2, 0.3),   // 光源相对受光面的方向
  options: const OhosPointLightOptions(
    color: Colors.white,
    intensity: 12,      // 光强
    height: 150,        // 光柱高度
  ),
  borderRadius: BorderRadius.circular(22),
  child: card,
)

// 发光源:卡片中心的圆钮
OhosLightSource(
  size: 34,
  options: const OhosPointLightOptions(intensity: 10, height: 150),
)

点光源实机效果(defaultFeatheringBorder 羽化亮边):

点光源效果(实机)

点光源:发光源朝受光面投射,defaultFeatheringBorder 类型产生羽化亮边

5.2 按压阴影

OhosPressShadow 对应 ArkUI visualEffect(pressShadow):按压时表面出现白色混合或指尖径向渐变,抬手淡出,强化"按下去"的触感:

OhosPressShadow(
  type: OhosPressShadowType.blendGradient,   // blendWhite / blendGradient
  borderRadius: BorderRadius.circular(24),
  child: card,
)
  • blendWhite:整面白色混合,适合纯色卡片;
  • blendGradient:以按压点为圆心的径向渐变,适合大图卡片,"指尖按压"观感更真实;
  • 按压阴影与 OhosLightSource 可以叠加使用:发光源本身作为受光对象,按压时光晕增强。

六、侧边栏与横滑列表

6.1 OhosSideBar 侧边栏

OhosSideBar 是宽屏场景的导航主力:overlay 悬浮侧边栏,圆角尾缘、半透明遮罩、点击外部自动收起、展开动画,内置一/二/三级菜单(OhosSideMenu / OhosSideMenuItem / OhosSideMenuSubItem),支持红点与数字角标:

OhosSideBar(
  isShowSideBar: _show,
  onIsShowSideBarChanged: (bool v) => setState(() => _show = v),
  overlay: true,
  width: 230,
  sideBar: OhosSideMenu(
    items: const [
      OhosSideMenuItem(label: '收件箱', icon: Icon(Icons.mail_outline_rounded)),
      OhosSideMenuItem(
        label: '消息',
        icon: Icon(Icons.chat_bubble_outline_rounded),
        badgeCount: 8,
        subItems: [
          OhosSideMenuSubItem(label: '短信', badgeCount: 50),
        ],
      ),
    ],
    selectedValue: _selected,
    onSelected: (String v) => setState(() => _selected = v),
  ),
  content: const MyPage(),
)

侧边栏 + 侧边菜单实机效果:

侧边栏与侧边菜单(实机)

侧边栏:overlay 悬浮、圆角尾缘、二级菜单展开态、红点与数字角标

6.2 OhosListItem 横滑列表项

OhosListItem 左滑显示操作按钮(对齐 ArkUI SwipeAction),支持整划删除:滑动越过阈值自动触发 onFullDelete 并移除该行:

OhosListItem(
  fullDelete: true,
  onFullDelete: () => setState(() => rows.removeAt(i)),
  actions: [
    OhosSwipeAction(
      icon: const Icon(Icons.share_rounded),
      backgroundColor: const Color(0xFF64BB5C),
      onTap: () {},
    ),
    OhosSwipeAction(
      icon: const Icon(Icons.delete_outline_rounded),
      backgroundColor: theme.dangerColor,
      onTap: () => setState(() => rows.removeAt(i)),
    ),
  ],
  child: row,
)

横滑列表项实机效果:

横滑列表项(展开操作按钮,实机)

横滑列表项:左划展开操作按钮,整划越过阈值自动删除

七、常驻通知与子页签分割线

7.1 常驻 SnackBar

showOhosSnackBar(resident: true) 是「常驻通知」能力的实现:duration -1 语义,常驻显示直到用户点击关闭按钮,支持"图标 + 标题 + 描述"的完整信息结构,也兼容传统"消息 + 撤销"组合:

// 常驻通知:网络断开提示
showOhosSnackBar(
  context,
  resident: true,
  icon: const Icon(Icons.wifi_off_rounded),
  title: 'Wi-Fi 已断开',
  content: '请检查网络后重试',
);

// 传统模式:消息 + 撤销
showOhosSnackBar(
  context,
  message: '已删除 1 个文件',
  actionLabel: '撤销',
  onAction: () => showOhosToast(context, '已撤销'),
);

常驻通知实机效果:

常驻通知 SnackBar(实机)

常驻通知:图标 + 标题 + 描述结构,常驻显示直到点击关闭按钮

7.2 子页签分割线跟手

OhosTabBar 通过 divider(OhosTabBarDividerOptions)提供三种分割线行为,followScroll 把分割线与滚动控制器绑定:内容下滑时分割线淡入、回到顶部淡出,让页签栏与内容流的关系更清晰:

DefaultTabController(
  length: 3,
  child: NestedScrollView(
    headerSliverBuilder: (_, __) => [
      SliverToBoxAdapter(
        child: OhosTabBar(
          tabs: const [Text('推荐'), Text('热榜'), Text('关注')],
          divider: const OhosTabBarDividerOptions(
            mode: OhosTabBarDividerMode.followScroll, // visible / none / followScroll
          ),
          scrollController: _scroller,
        ),
      ),
    ],
    body: TabBarView(children: [page1, page2, page3]),
  ),
)

子页签分割线实机效果(visible 常显模式):

子页签分割线(实机)

子页签:分割线常显 / 常隐 / 跟手三种模式

八、可展开操作栏与分层图标

8.1 OhosActionBar 可展开操作栏

OhosActionBar(expandable: true) 是悬浮宫格操作栏:主按钮点击后展开次级操作,对齐官方「核心操作栏 + 可展开」能力:

OhosActionBar(
  expandable: true,
  isExpanded: _expanded,
  onIsExpandedChanged: (bool v) => setState(() => _expanded = v),
  primaryIcon: Icons.add_rounded,      // 收起态显示 +,展开态自动切换为关闭
  primaryTooltip: '新建内容',
  onPrimaryPressed: () {},
  secondaryActions: [
    OhosButton(style: OhosButtonStyle.text, onPressed: () {}, child: const Text('笔记')),
    OhosButton(style: OhosButtonStyle.text, onPressed: () {}, child: const Text('拍照')),
    OhosButton(style: OhosButtonStyle.text, onPressed: () {}, child: const Text('视频')),
  ],
)

可展开操作栏实机效果:

可展开操作栏(实机)

可展开操作栏:主按钮展开宫格次级操作

8.2 分层图标与多窗入口

  • OhosLayeredIcon:背景板 + 前景图标合成,支持缩放与描边,用于应用图标、功能入口的"分层"设计语言;
  • OhosMultiWindowEntry:应用内多窗入口,无多窗能力的设备自动禁用(灰化、不可点),业务侧无需自行判断设备能力。
OhosLayeredIcon(
  background: Container(
    width: 96,
    height: 96,
    decoration: BoxDecoration(
      color: const Color(0xFF0A59F7),
      borderRadius: BorderRadius.circular(22),
    ),
  ),
  icon: const Icon(Icons.square_footprint, size: 48, color: Colors.white),
)

OhosMultiWindowEntry(onTap: () => _openMultiWindow())

分层图标与多窗入口实机效果:

分层图标与多窗入口(实机)

分层图标:背景板 + 前景图标合成;多窗入口在无能力设备自动灰化禁用

九、与转场动效配合

UI Design Kit 的"光"需要动效才能活起来。OhosGeometry 提供与官方转场动效一致的曲线与时长:

  • OhosGeometry.spring(90ms):按压反馈,与按压阴影、光池按压光晕配套;
  • OhosGeometry.easeOut(200/400ms):界面转场,侧边栏展开、弹层出入使用;
  • OhosGeometry.sharedElement(300ms):一镜到底共享元素转场。

共享元素"一镜到底"转场实机效果:

一镜到底共享元素转场(实机)

一镜到底:列表卡片点击后放大过渡到详情页,sharedElement 曲线 300ms

动效曲线对比与转场演示页:

转场动效(曲线对比,实机)

转场动效:spring / easeOut / sharedElement 曲线对比演示

十、模拟器实测与调优

在 OpenHarmony 模拟器(API 26,1280×2832)上实测的几点经验:

  1. 模拟器不支持原生 HDS 光影:官方文档明确,原生 PointLight / pressShadow 等 HDS 效果在模拟器不可用——harmony_ui 的自绘实现反而成为模拟器上唯一可见"光感"的方式,真机与模拟器的视觉一致;
  2. 模糊开销:BlurBackdropFilter 在 1280 宽屏上帧率无压力,但多层叠加(标题栏 + 悬浮页签 + 弹层同时)会叠加,注意同一时刻模糊层数量;
  3. 调参顺序:先定档位(level),再调 glowScale,最后动 blurScale;scatterScale 默认保持 0,只在半模态中按需开启;
  4. 深色模式:光池配色随主题自动切换,深色下建议 glowScale 略降(0.8~0.9)避免过曝;
  5. 构建路径:fvm flutter build hap --debug --no-codesign + hdc install,模拟器免签名,UI 改动热重载即可见。

总结

沉浸光感与 UI Design Kit 是 HarmonyOS 设计语言"灵魂"所在。harmony_ui 用纯 Dart 自绘把五档毛玻璃材质、点光源、按压阴影、动态模糊标题栏、侧边栏、横滑列表、常驻通知等能力全部落地,并且与基础组件、转场动效无缝组合——在 Flutter 上做出"像原生鸿蒙"的 UI,从本篇开始只需要打开几个开关。

至此,本系列共 7 篇——官方六大控件类别各一篇、增强类收官一篇——全部完结。更多可交互示例可运行仓库 example/ 下的 gallery 应用,全部控件与增强能力均可在模拟器上实际体验。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

  • harmony_ui 仓库(AtomGit):https://atomgit.com/oh-flutter/harmony_ui
  • harmony_ui 仓库(GitHub):https://github.com/shaohushuo/harmony_ui
  • 开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
  • 鸿蒙社区 Flutter 分叉:https://atomgit.com/CPF-Flutter/flutter_flutter
  • 华为 UI Design Kit 能力文档:https://developer.huawei.com/consumer/cn/doc/doccenter-capabilities/ui-design-introduction.md
  • 官方沉浸光感规范:https://developer.huawei.com/consumer/cn/doc/doccenter-ux-design/immersivelight-0000002612101053
  • 官方转场动效规范:https://developer.huawei.com/consumer/cn/doc/doccenter-ux-design/design-concepts-0000001795698445
  • 光感 TabBar 技术参考(MIT):https://gitcode.com/ZuoYueLiang/harmony_immersive_glow_tabbar
  • liquid_glass_widgets(技术参考):https://pub.dev/packages/liquid_glass_widgets
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐