HarmonyKit | 鸿蒙新特性HDS 组件体系 kit.UIDesignKit 完全解读引言两个 Tabs 的故事HarmonyKit 的代码库中有且仅有一个 HDS 组件——HdsTabs。但就这一个组件经历了三次迭代、两种 Tabs 实现的对比、以及从 80 行手动毛玻璃代码到 7 个链式属性的精简过程。为什么是 HdsTabs 而不是 HdsNavigation为什么没有迁移全部 10 个工具页到 HDS 体系这篇文章会从实战出发详细讲解 HDS 组件体系的设计理念、核心组件的能力边界、与基础 ArkUI 组件的本质区别、以及 HarmonyKit 在用与不用之间的决策逻辑。项目仓库https://atomgit.com/VON-/harmony-kitHDS 是什么设计规范的可执行版本HDSHarmony Design System是鸿蒙官方的设计规范系统。在代码层面它被封装在kit.UIDesignKit中以一组前缀为Hds的 UI 组件暴露给开发者HdsTabs、HdsNavigation、HdsNavDestination、MiniBar 等。HDS 和 ArkUI 基础组件的关系类似于 Material Design 组件库和 Android View 系统的关系。ArkUI 的Tabs组件提供了基础的标签页功能——切换 Tab、显示内容、自定义 Tab 栏位置。HDS 的HdsTabs在Tabs的基础上加了一层设计规范——悬浮胶囊形状、沉浸光感材质、自适应握姿偏移、MiniBar 动态切换。这些规范特性在基础 Tabs 上不是做不到而是需要手动实现——你需要自己写 backdropBlur、自己调圆角半径、自己管理切换动画。HDS 的存在价值就是消除这些重复劳动。在 HarmonyKit 中引入 HDS 的方式是import{hdsMaterial,HdsTabs,HdsTabsController}fromkit.UIDesignKit;一行 import 引入了三个关键要素HdsTabsHDS 版本的标签页组件用于构建底部导航HdsTabsControllerHDS 标签页的状态管理器提供程序化切换 Tab 的能力hdsMaterial命名空间包含了 MaterialType 和 MaterialLevel 枚举值用于配置沉浸光感这三个导入各自承担不同的职责。HdsTabs是 UI 组件主体HdsTabsController是状态控制器hdsMaterial是配置选项。三者分离的设计避免了一个巨大组件承担一切的臃肿结构。HDS 组件的全景图HarmonyOS 目前提供了以下几类核心 HDS 组件HdsTabsHDS 版标签页导航这是 HarmonyKit 唯一在用的 HDS 组件。HdsTabs替代了基础Tabs组件在底部导航场景中提供了以下增强能力悬浮胶囊形态通过barFloatingStyle配置导航栏呈现圆角胶囊形状两端留有空隙看起来像是悬浮在屏幕底部而非贴边。这与 iOS 从 iOS 13 开始引入的悬浮式 Tab Bar 是同一个设计方向——从矩形贴边导航进化为胶囊悬浮导航。沉浸光感材质通过systemMaterialEffect配置导航栏的背景不是纯色而是动态感知下层内容光影的物理材质。这个特性在上一篇文章#11 沉浸光感中有详细分析。MiniBar 动态切换当用户滚动较长距离后完整的导航栏可以动画收缩为紧凑的 MiniBar——只保留关键信息节省屏幕空间。这个特性在内容密集型应用新闻、社交、电商中非常有价值但在 HarmonyKit 这种工具应用的短列表中意义不大。智感握姿通过adaptToHandedness: true启用系统感知用户握持手并微调导航栏中心点偏移。HarmonyKit 中 HdsTabs 的完整配置HdsTabs({controller:this.controller}){ForEach(CATEGORIES,(cat:string){TabContent(){this.ToolGrid(cat)}.tabBar(cat)})}.barOverlap(true).vertical(false).barPosition(BarPosition.End).barFloatingStyle({barBottomMargin:36,adaptToHandedness:true,systemMaterialEffect:{materialType:hdsMaterial.MaterialType.ADAPTIVE,materialLevel:hdsMaterial.MaterialLevel.ADAPTIVE}}).layoutWeight(1)7 个链式属性构成了完整的底部导航。每个属性的存在必要性barOverlap(true)让内容区扩展到全屏导航栏悬浮覆盖在内容之上。这是沉浸光感的前置条件。vertical(false)指明这是水平排列的 Tab 栏而非垂直侧边栏默认值就是 false显式写出是为了代码可读性。barPosition(BarPosition.End)导航栏在屏幕底部。可选 Start顶部但在移动端几乎没有顶部 Tab 搭配沉浸光感的场景。barFloatingStyle悬浮样式配置对象包含底部间距、握姿适配、系统材质三个子配置。layoutWeight(1)HdsTabs 占据剩余的全部垂直空间。没有这个属性HdsTabs 的高度可能不会填满屏幕剩余区域。HdsNavigation 与 HdsNavDestinationHDS 版页面导航HdsNavigation是Navigation的 HDS 版本用于管理应用内的页面栈和页面跳转。HdsNavDestination是NavDestination的 HDS 版本用于定义导航栈中的单个目标页面。两者配合使用时的典型写法HdsNavigation(){// 内容区}.titleMode(NavigationTitleMode.Full).mode(NavigationMode.Stack)HdsNavigation 的核心增强包括标题栏自动材质效果滚动时从透明过渡到模糊标题栏与内容之间的渐变模糊过渡动态显隐标题栏根据滚动方向自动显示/隐藏与 NavPathStack 的原生集成HdsNavDestination 的增强包括独立的 titleBar 配置每个页面可自定义标题栏样式scrollEffect属性自定义滚动时标题栏的变化行为与 HdsNavigation 的材质效果自动协同MiniBar紧凑导航栏MiniBar 是 HdsTabs 的一个子特性。当用户在 Tab 内容区向下滚动一定距离后完整的悬浮导航栏可以动画过渡为一个更紧凑的版本。MiniBar 通常只保留图标或缩写标签去掉完整的文字描述。配置 MiniBar 需要在 HdsTabs 上使用.miniBar()属性传入一个 Builder 函数定义 MiniBar 的外观HdsTabs({controller:this.controller}){// TabContent...}.miniBar(this.miniBarBuilder)MiniBar 在 HarmonyKit 中未被使用因为工具网格通常不超过 3 屏高度滚动距离不足以触发 MiniBar 的切换阈值。HDS 组件 vs 基础 ArkUI 组件能力的边界下面是一张 HDS 与基础组件的对比表以 Tabs/HdsTabs 为例维度基础 TabsHdsTabs悬浮效果不支持需手动 Stack 叠加barOverlap(true)一行启用毛玻璃材质需backdropBlur()手动调参systemMaterialEffect内置ADAPTIVE 自动适配圆角胶囊形状需自定义 Builder 和手动 borderRadiusbarFloatingStyle系统级自动智感握姿不支持adaptToHandedness启用性能自适应需手动检测 GPU 能力ADAPTIVE 档位自动分级MiniBar不支持.miniBar()Builder 配置iOS/Android 一致性需自行维护HDS 框架保证跨系统一致性自定义灵活性极高TabBuilder 完全控制低tabBar 仅支持字符串/简单样式系统版本兼容基础组件SDK 5.0 均可用部分特性需 SDK 6.1.0学习成本低常规 Tabs 心智模型中需要理解 HDS 设计规范概念这张表的核心洞察是HDS 组件通过牺牲一定程度的自定义灵活性换来了开箱即用的设计规范一致性。如果你接受 HDS 的设计语言圆角胶囊、毛玻璃、自适应HdsTabs 几乎不需要调参。如果你想做完全自定义的底部导航栏比如竖排标签、图标文字组合、非矩形的指示器线条那么基础 Tabs 自定义 Builder 才是正解。HarmonyKit 的 HDS 使用决策为什么 HarmonyKit 只在底部导航用了 HdsTabs而没有全面迁移到 HDS 体系决策一用 HdsTabs 替代基础 Tabs理由非常直接底部导航恰好是沉浸光感发挥最大价值的场景。用户切换到不同工具分类时可以看到工具网格在导航栏下方流动毛玻璃模糊材质营造出物理层次的错觉。而 HdsTabs 只用一行配置就能达到这个效果。在基础 Tabs 上手动实现同样的效果需要约 80 行代码——包括 Stack 容器、backdropBlur 属性、自定义选中状态管理、手势跟随逻辑。HdsTabs 提供的不仅是代码量减少更是代码质量的提升——手动实现的那 80 行代码中的任何一个疏忽比如忘记在某些设备上关闭模糊效果导致卡顿都可能成为线上 bug。决策二不用 HdsNavigationHarmonyKit 的页面导航使用了传统的router.pushUrl()模式而不是 NavPathStack 体系。这是基于两个考虑架构简单性HarmonyKit 的页面结构是 2 层——主页Index和 10 个工具页JsonFormatter、Base64Tool 等。每个工具页有独立的返回按钮点击后通过this.getUIContext().getRouter().back()回到主页。页面栈深度不超过 2 层没有嵌套导航没有多级跳转。在这种简单结构下传统的路由器 API 已经足够。来看一个工具页的典型导航代码Button({type:ButtonType.Circle}){Image($r(sys.media.ohos_ic_public_arrow_left)).width(24).height(24).fillColor(#333333)}.width(32).height(32).backgroundColor(Color.Transparent).onClick(()this.getUIContext().getRouter().back());每个工具页的顶部都有一个系统级别的返回箭头按钮。点击后调用getRouter().back()返回上一页。这是最基础的导航操作——不需要 NavPathStack 的多栈管理能力。迁移成本HdsNavigation 要求所有子页面通过navDestinationBuilder 构建而不是通过router.pushUrl()直接跳转。这意味着需要为 10 个工具页编写路由映射函数或者使用 NavPathStack 的命名路由。虽然代码量不多但在当前架构已经简洁且功能完整的前提下迁移的收益-成本比不高。// 如果用 NavPathStack 体系需要构建路由映射BuilderNavMap(name:string,_param:Object){if(namejson){JsonFormatterPage()}elseif(namebase64){Base64ToolPage()}elseif(namehash){HashCalculatorPage()}// ... 10 个工具页10 行 if-else}这种路由映射虽然在大型应用中很常见但对于 HarmonyKit 的 2 层页面结构来说10 行 if-else 并不比在main_pages.json中声明 10 行路由路径更简洁。决策三不用 MiniBar如前所述工具网格的滚动距离不够触发 MiniBar。强行启用 MiniBar 只会增加代码复杂度而没有实际的用户体验提升。应该在需要的时候才用而不是能用就用。从基础 Tabs 到 HdsTabs 的迁移指南如果你正在考虑将项目的 Tabs 迁移到 HdsTabs以下步骤基于 HarmonyKit 的实战经验步骤一替换 import// 旧的import{Tabs}from...;// 通常不需要显式 importTabs 是全局可用的// 新的import{HdsTabs,HdsTabsController,hdsMaterial}fromkit.UIDesignKit;步骤二添加 Controllerprivatecontroller:HdsTabsControllernewHdsTabsController();Controller 是必须的——HdsTabs 要求显式传入 controller 实例。它提供了程序化控制 Tab 切换的接口controller.changeIndex(n)。步骤三配置悬浮和材质// 新增这三行.barOverlap(true).barFloatingStyle({barBottomMargin:36,adaptToHandedness:true,systemMaterialEffect:{materialType:hdsMaterial.MaterialType.ADAPTIVE,materialLevel:hdsMaterial.MaterialLevel.ADAPTIVE}})步骤四调整内容区 padding由于barOverlap(true)让内容区扩展到全屏原来止步于导航栏之上的内容现在会被导航栏遮挡。需要在内容区的底部增加 padding// 旧的值.padding({left:16,right:16,top:8,bottom:16})// 新的值增加底部 padding 以避开悬浮导航栏.padding({left:16,right:16,top:8,bottom:80})底部 padding 的具体数值取决于导航栏的高度和barBottomMargin。经验公式是bottom 导航栏高度 barBottomMargin 安全区域高度。步骤五在低端设备上验证降级效果在compatibleSdkVersion较低的目标设备如 6.0.2上运行应用验证降级后的视觉效果是否可接受。在 HarmonyKit 的测试中6.0.2 设备上 HdsTabs 降级为基础矩形导航栏——虽然失去了模糊和悬浮效果但功能依然完整。HDS 设计系统的长远价值HDS 组件相对于基础组件的最深远价值不在于当前版本的视觉效果更好而在于未来版本的视觉规范会自动更新。当 HarmonyOS 在设计层面更新底部导航的圆角半径、间距标准或材质渲染算法时使用基础 Tabs 硬编码样式的应用需要手动跟进——逐一检查每个页面的borderRadius、backdropBlur参数是否与新规一致。使用 HdsTabs 的应用则自动获得更新——因为系统在下层应用了新的设计规范。这就是设计规范代码化的核心优势你不是在写样式代码你是在声明我遵循 HDS 设计规范。规范变更时你不需要改一行代码。对于 HarmonyKit 这类工具应用来说紧跟系统设计规范是合理的策略。工具应用应该融入系统而不是挑战系统的设计语言。用户打开 HarmonyKit 应该感到这是一个原生体验的应用而不是一个自定义了特殊视觉风格的应用。HDS 组件恰好帮助实现这个目标。总结HDS 组件体系代表了鸿蒙 UI 开发从底层 API 暴露到设计规范封装的进化。基础 ArkUI 组件提供底层能力你可以用它们实现任何视觉效果HDS 组件提供设计规范你用它们自动获得符合官方设计指南的视觉效果。HarmonyKit 的 HDS 使用策略是务实的在沉浸光感价值最大的场景底部导航全面采用 HdsTabs在不适合的场景2 层简单页面导航保持基础路由器 API。不为了用 HDS而用 HDS而是在 HDS 确实带来明确价值的地方才使用。对于正在构建鸿蒙应用的开发者建议的选择策略是如果你在做底部导航优先选择 HdsTabs——沉浸光感自动适配省去大量手写代码如果你在做复杂多级页面导航考虑 HdsNavigation NavPathStack——动态标题栏和材质过渡效果值得迁移成本如果你的导航结构简单2-3 层以内基础 Router API 已经足够——不要为了一致性而过早引入复杂度如果你有独特的设计稿且与 HDS 规范不同继续使用基础组件 自定义样式——HDS 不是强制的它只是推荐的默认选择项目仓库https://atomgit.com/VON-/harmony-kit