HarmonyOS 6(API 23)实战:基于悬浮导航与沉浸光感的“智流工坊“——PC端低代码智能体编排平台
文章目录

每日一句正能量
“重要的不是经历什么,而是如何诠释这些经历。”
同样失业,有人诠释为“我完了”,有人诠释为“终于可以换赛道”。经历是客观事件,诠释是主观选择。把诠释权握在自己手里,人就永远不是命运的受害者。
前言
摘要:随着AI智能体应用的爆发式增长,非技术用户快速构建智能体应用的需求日益迫切。HarmonyOS 6(API 23)引入的鸿蒙智能体框架(HMAF)配合小艺开放平台的四种编排模式,为低代码可视化智能体开发提供了全新可能。本文将实战开发一款面向HarmonyOS PC的"智流工坊"应用,展示如何利用HMAF构建拖拽式可视化智能体编排引擎,通过悬浮导航实现画布与组件库状态实时切换,基于沉浸光感打造"节点即氛围"的编排体验,以及基于多窗口架构构建浮动属性面板、预览窗口和调试控制台窗口的协作开发体验。
一、前言:低代码智能体编排的范式革新
2026年,AI智能体已从技术极客的玩具演变为企业数字化转型的核心引擎。蚂蚁数科Agentar、Dify、Coze等低代码智能体平台的崛起,证明了"可视化编排+智能体协同"模式的巨大市场潜力。然而,这些平台大多运行在Web端,缺乏原生操作系统的深度集成能力。
HarmonyOS 6(API 23)的HMAF框架不仅支持LLM模式、工作流模式、A2A模式和OpenClaw模式四种编排方式,更关键的是将智能体能力下沉至操作系统层,配合**悬浮导航(Float Navigation)与沉浸光感(Immersive Light Effects)**特性,为PC端低代码智能体编排带来了"节点即氛围、连线即光效"的全新交互范式。
本文核心亮点:
- 节点类型光效:根据智能体节点类型(LLM节点/工具节点/条件节点/循环节点/输出节点)动态切换环境光色与脉冲节奏
- 悬浮编排导航:底部悬浮页签替代传统工具栏,支持画布缩放、节点库切换、运行状态实时徽章
- HMAF可视化编排引擎:基于Agent Framework Kit构建拖拽式节点编排引擎,支持四种编排模式无缝切换
- 多窗口协作开发:主画布窗口 + 浮动属性面板 + 浮动预览窗口 + 浮动调试控制台窗口的光效联动
- 运行状态沉浸感知:通过Intents Kit实时理解编排意图,自动调整界面光效与导航形态

二、核心特性解析与技术选型
2.1 沉浸光感在智能体编排中的价值
HarmonyOS 6的systemMaterialEffect通过模拟物理光照模型,为标题栏和导航组件带来细腻的光晕与反射效果。在智能体编排场景中,这种材质效果能够:
- 增强节点辨识度:不同节点类型对应不同光色,LLM节点散发智慧紫光、工具节点呈现工具橙光,一眼即可区分
- 营造编排氛围:玻璃拟态的半透明层让背景光效柔和过渡,营造"在星空中连线"的科技感
- 状态即时感知:节点运行时光效脉冲变化,成功时泛绿光、失败时泛红光,无需查看日志即可掌握状态
2.2 悬浮导航的编排工作台适配
与传统移动端应用不同,PC端智能体编排工作台需要处理:
- 高频模式切换:开发者常在LLM模式、工作流模式、A2A模式、OpenClaw模式间快速切换
- 信息密度平衡:既要保证导航可见,又不能压缩画布编辑区域
- 鼠标优先交互:悬停预览、右键节点菜单、中键平移画布等桌面级操作
HarmonyOS 6的悬浮页签支持**强(85%)、平衡(70%)、弱(55%)**三档透明度自定义,结合PC端的自由窗口能力,可以实现"需要时出现,专注时隐退"的智能导航体验。
2.3 技术架构选型
| 技术模块 | 选用方案 | 说明 |
|---|---|---|
| 智能体框架 | HMAF (HarmonyOS Multi-Agent Framework) | 系统级智能体编排能力 |
| 意图理解 | Intents Kit | 拖拽意图实时解析 |
| 窗口管理 | Window Manager + 子窗口 | 多窗口协作架构 |
| 渲染引擎 | Canvas + Gesture | 自定义节点画布 |
| 状态管理 | AppStorage | 跨组件/跨窗口状态同步 |
| 光效系统 | SystemMaterialEffect + 自定义动画 | 沉浸光感实现 |

三、项目实战:"智流工坊"架构设计
3.1 应用场景与功能规划
面向HarmonyOS PC的低代码可视化智能体编排场景,核心功能包括:
| 功能模块 | 技术实现 | 沉浸光感/HMAF应用 |
|---|---|---|
| 主画布窗口 | Canvas + Gesture |
节点光效、连线流光、吸附高亮 |
| 悬浮编排导航 | HdsTabs + systemMaterialEffect |
玻璃拟态页签,模式徽章 |
| 节点库面板 | Grid + Drag |
节点类型色光效 |
| 属性面板 | Form + HdsInput |
选中节点主题色同步 |
| LLM编排模式 | HMAF LLM Mode | 智慧紫光效 |
| 工作流编排模式 | HMAF Workflow Mode | 流程蓝光效 |
| A2A编排模式 | HMAF A2A Mode | 通信青光效 |
| OpenClaw编排模式 | HMAF OpenClaw Mode | 轻量粉光效 |
| 浮动预览窗口 | 子窗口 + WebView |
运行状态光效 |
| 浮动调试控制台 | 子窗口 + List |
日志级别颜色编码 |
3.2 技术架构图
┌─────────────────────────────────────────────────────────────┐
│ 智流工坊 - 智能体编排平台 │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 沉浸光感层 │ │ 主画布层 │ │ 悬浮导航层 │ │
│ │ (Ambient) │ │ (Canvas) │ │ (FloatNav) │ │
│ │ 动态环境光 │ │ 节点编排 │ │ 模式切换 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 浮动属性面板 │ │ 浮动预览窗口 │ │ 浮动调试控制台│ │
│ │ (SubWindow) │ │ (SubWindow) │ │ (SubWindow) │ │
│ │ 节点配置 │ │ 实时运行效果 │ │ 日志与调试 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ HMAF编排引擎 (LLM/Workflow/A2A/OpenClaw) + Intents Kit │
└─────────────────────────────────────────────────────────────┘
四、环境配置与模块依赖
4.1 模块依赖配置
// entry/oh-package.json5
{
"dependencies": {
"@kit.UIDesignKit": "^1.0.0",
"@kit.ArkUI": "^1.0.0",
"@kit.AgentFrameworkKit": "^1.0.0",
"@kit.IntentsKit": "^1.0.0",
"@kit.WindowManagerKit": "^1.0.0"
}
}
4.2 权限声明(module.json5)
{
"module": {
"name": "entry",
"type": "entry",
"description": "智流工坊 - 智能体编排平台",
"mainElement": "EntryAbility",
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "主编排窗口",
"icon": "$media:icon",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:icon",
"startWindowBackground": "$color:start_window_background",
"windowMode": "fullscreen",
"supportWindowMode": ["fullscreen", "split", "float"]
}
],
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
},
{
"name": "ohos.permission.GET_NETWORK_INFO"
}
]
}
}
五、核心组件实战
5.1 窗口沉浸配置(EntryAbility.ets)
// entry/src/main/ets/entryability/EntryAbility.ets
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: window.WindowStage): void {
// 加载主页面
windowStage.loadContent('pages/EditorPage', (err) => {
if (err.code) {
console.error('Failed to load content:', JSON.stringify(err));
return;
}
console.info('Succeeded in loading content.');
// 获取主窗口并配置沉浸模式
let mainWindow = windowStage.getMainWindowSync();
this.configureImmersiveWindow(mainWindow);
});
}
private configureImmersiveWindow(mainWindow: window.Window): void {
// 设置窗口全屏布局,移除系统标题栏
mainWindow.setWindowLayoutFullScreen(true);
// 设置窗口背景为透明,让沉浸光效穿透
mainWindow.setWindowBackgroundColor('#00000000');
// 设置窗口亮度跟随内容
mainWindow.setWindowKeepScreenOn(true);
// 监听窗口焦点变化,同步到全局状态
mainWindow.on('windowFocusChange', (isFocused: boolean) => {
AppStorage.setOrCreate('window_focused', isFocused);
});
}
}
代码亮点:
setWindowLayoutFullScreen(true):移除系统标题栏,实现真正的无边框沉浸体验setWindowBackgroundColor('#00000000'):透明背景让底层光效层完全可见windowFocusChange监听:窗口焦点状态同步到AppStorage,供全应用组件响应
5.2 沉浸光感标题栏(ImmersiveTitleBar.ets)
// entry/src/main/ets/components/ImmersiveTitleBar.ets
import { HdsNavigation, SystemMaterialEffect } from '@kit.UIDesignKit';
@Component
export struct ImmersiveTitleBar {
@Prop currentMode: string = 'LLM'; // LLM | Workflow | A2A | OpenClaw
@State isWindowFocused: boolean = true;
@State titleBarHeight: number = 48;
// 编排模式主题色映射
private modeColors: Map<string, string> = new Map([
['LLM', '#7B61FF'], // 智慧紫
['Workflow', '#00B4D8'], // 流程蓝
['A2A', '#00C9A7'], // 通信青
['OpenClaw', '#FF6B9D'] // 轻量粉
]);
aboutToAppear(): void {
// 监听窗口焦点变化,调整光效强度
AppStorage.watch('window_focused', (focused: boolean) => {
this.isWindowFocused = focused;
});
}
private getThemeColor(): string {
return this.modeColors.get(this.currentMode) || '#7B61FF';
}
build() {
HdsNavigation({
title: `智流工坊 - ${this.currentMode}模式`,
subtitle: 'HarmonyOS PC 智能体编排',
// 核心:启用沉浸光感材质
systemMaterialEffect: SystemMaterialEffect.IMMERSIVE,
// 背景透明度随焦点状态变化
backgroundOpacity: this.isWindowFocused ? 0.85 : 0.55,
// 标题栏高度
height: this.titleBarHeight,
// 左侧操作区:编排控制
leading: this.buildLeadingActions(),
// 右侧操作区:窗口与设置
trailing: this.buildTrailingActions()
})
.width('100%')
// 动态光效边框:窗口激活时增强发光
.border({
width: { bottom: 1 },
color: this.isWindowFocused
? this.getThemeColor()
: 'rgba(255,255,255,0.1)'
})
.shadow({
radius: this.isWindowFocused ? 15 : 5,
color: this.getThemeColor(),
offsetX: 0,
offsetY: 2
})
.animation({
duration: 300,
curve: Curve.EaseInOut
})
}
@Builder
buildLeadingActions(): void {
Row({ space: 12 }) {
// 运行编排按钮
Button({ type: ButtonType.Circle }) {
Image($r('app.media.ic_play'))
.width(18)
.height(18)
.fillColor('#FFFFFF')
}
.width(32)
.height(32)
.backgroundColor('rgba(123, 97, 255, 0.3)')
.onClick(() => {
// 触发编排运行
AppStorage.setOrCreate('agent_action', 'run_workflow');
})
// 暂停按钮
Button({ type: ButtonType.Circle }) {
Image($r('app.media.ic_pause'))
.width(18)
.height(18)
.fillColor('#FFFFFF')
}
.width(32)
.height(32)
.backgroundColor('rgba(255, 193, 7, 0.3)')
.onClick(() => {
AppStorage.setOrCreate('agent_action', 'pause_workflow');
})
// 保存编排按钮
Button({ type: ButtonType.Circle }) {
Image($r('app.media.ic_save'))
.width(18)
.height(18)
.fillColor('#FFFFFF')
}
.width(32)
.height(32)
.backgroundColor('rgba(76, 175, 80, 0.3)')
.onClick(() => {
AppStorage.setOrCreate('agent_action', 'save_workflow');
})
}
.padding({ left: 16 })
}
@Builder
buildTrailingActions(): void {
Row({ space: 12 }) {
// 打开属性面板
Button({ type: ButtonType.Circle }) {
Image($r('app.media.ic_properties'))
.width(18)
.height(18)
.fillColor('#FFFFFF')
}
.width(32)
.height(32)
.backgroundColor('rgba(255,255,255,0.1)')
.onClick(() => {
AppStorage.setOrCreate('window_action', 'open_properties');
})
// 打开预览窗口
Button({ type: ButtonType.Circle }) {
Image($r('app.media.ic_preview'))
.width(18)
.height(18)
.fillColor('#FFFFFF')
}
.width(32)
.height(32)
.backgroundColor('rgba(255,255,255,0.1)')
.onClick(() => {
AppStorage.setOrCreate('window_action', 'open_preview');
})
// 打开调试控制台
Button({ type: ButtonType.Circle }) {
Image($r('app.media.ic_terminal'))
.width(18)
.height(18)
.fillColor('#FFFFFF')
}
.width(32)
.height(32)
.backgroundColor('rgba(255,255,255,0.1)')
.onClick(() => {
AppStorage.setOrCreate('window_action', 'open_console');
})
// 设置按钮(长按展开透明度调节)
Button({ type: ButtonType.Circle }) {
Image($r('app.media.ic_settings'))
.width(18)
.height(18)
.fillColor('#FFFFFF')
}
.width(32)
.height(32)
.backgroundColor('rgba(255,255,255,0.1)')
.gesture(
LongPressGesture({ duration: 500 })
.onAction(() => {
AppStorage.setOrCreate('show_transparency_panel', true);
})
)
}
.padding({ right: 16 })
}
}
代码亮点:
SystemMaterialEffect.IMMERSIVE:启用HDS系统级沉浸光感材质,标题栏自动获得物理光照效果- 动态
backgroundOpacity:窗口失焦时自动降低透明度,减少背景干扰 - 模式感知光效:根据当前编排模式(LLM/Workflow/A2A/OpenClaw)动态切换主题色,从标题栏发光到边框颜色形成统一视觉语言
- 微交互动画:所有状态变化均配备300ms的缓动动画,视觉过渡自然流畅
5.3 智能体节点画布(AgentCanvas.ets)
// entry/src/main/ets/components/AgentCanvas.ets
import { HMAFAgent, HMAFNodeType } from '@kit.AgentFrameworkKit';
interface AgentNode {
id: string;
type: HMAFNodeType;
x: number;
y: number;
label: string;
config: Record<string, any>;
status: 'idle' | 'running' | 'success' | 'error';
}
interface AgentEdge {
id: string;
from: string;
to: string;
label?: string;
}
@Component
export struct AgentCanvas {
@State nodes: AgentNode[] = [];
@State edges: AgentEdge[] = [];
@State selectedNodeId: string = '';
@State scale: number = 1.0;
@State offsetX: number = 0;
@State offsetY: number = 0;
@State isDragging: boolean = false;
@State dragStartX: number = 0;
@State dragStartY: number = 0;
// 节点类型光色映射
private nodeColors: Map<HMAFNodeType, string> = new Map([
[HMAFNodeType.LLM, '#7B61FF'], // 智慧紫
[HMAFNodeType.TOOL, '#FF9F1C'], // 工具橙
[HMAFNodeType.CONDITION, '#00C9A7'], // 条件青
[HMAFNodeType.LOOP, '#FF6B9D'], // 循环粉
[HMAFNodeType.OUTPUT, '#4CC9F0'] // 输出蓝
]);
// 节点状态光效映射
private statusEffects: Map<string, { color: string; pulse: boolean }> = new Map([
['idle', { color: 'rgba(255,255,255,0.6)', pulse: false }],
['running', { color: '#00E676', pulse: true }],
['success', { color: '#00C853', pulse: false }],
['error', { color: '#FF1744', pulse: true }]
]);
aboutToAppear(): void {
// 初始化示例编排:LLM -> 工具 -> 输出
this.nodes = [
{ id: 'n1', type: HMAFNodeType.LLM, x: 200, y: 200, label: 'GPT-4o', config: { model: 'gpt-4o' }, status: 'idle' },
{ id: 'n2', type: HMAFNodeType.TOOL, x: 400, y: 200, label: '搜索工具', config: { tool: 'web_search' }, status: 'idle' },
{ id: 'n3', type: HMAFNodeType.OUTPUT, x: 600, y: 200, label: '结果输出', config: { format: 'markdown' }, status: 'idle' }
];
this.edges = [
{ id: 'e1', from: 'n1', to: 'n2', label: '查询' },
{ id: 'e2', from: 'n2', to: 'n3', label: '结果' }
];
}
build() {
Stack() {
// 网格背景层
this.buildGridBackground()
// 连线层
Canvas(this.context2D)
.width('100%')
.height('100%')
.onReady((context) => {
this.drawEdges(context);
})
// 节点层
ForEach(this.nodes, (node: AgentNode) => {
this.buildNode(node)
}, (node: AgentNode) => node.id)
// 拖拽遮罩层
if (this.isDragging) {
Column()
.width('100%')
.height('100%')
.backgroundColor('rgba(123, 97, 255, 0.05)')
.border({ width: 2, color: '#7B61FF', style: BorderStyle.Dashed })
}
}
.width('100%')
.height('100%')
.backgroundColor('#0a0a0f')
.gesture(
PanGesture()
.onActionStart((event) => {
this.isDragging = true;
this.dragStartX = event.offsetX;
this.dragStartY = event.offsetY;
})
.onActionUpdate((event) => {
this.offsetX += event.offsetX - this.dragStartX;
this.offsetY += event.offsetY - this.dragStartY;
this.dragStartX = event.offsetX;
this.dragStartY = event.offsetY;
})
.onActionEnd(() => {
this.isDragging = false;
})
)
.scale({ x: this.scale, y: this.scale })
.translate({ x: this.offsetX, y: this.offsetY })
}
@Builder
buildGridBackground(): void {
Column()
.width('100%')
.height('100%')
.backgroundImage($r('app.media.grid_pattern'))
.backgroundImageSize({ width: '40px', height: '40px' })
.backgroundImagePosition({ x: 0, y: 0 })
.opacity(0.3)
}
@Builder
buildNode(node: AgentNode): void {
Stack() {
// 节点光晕效果
Column()
.width(120)
.height(120)
.backgroundColor(this.nodeColors.get(node.type))
.blur(40)
.opacity(this.getNodeGlowOpacity(node))
.position({ x: 0, y: 0 })
.animation({
duration: 2000,
curve: Curve.EaseInOut,
iterations: node.status === 'running' ? -1 : 0,
playMode: PlayMode.Alternate
})
.scale({ x: 1.5, y: 1.5 })
// 节点主体
Column() {
// 节点图标
Image(this.getNodeIcon(node.type))
.width(32)
.height(32)
.fillColor('#FFFFFF')
.margin({ top: 12 })
// 节点标签
Text(node.label)
.fontSize(12)
.fontColor('#FFFFFF')
.margin({ top: 8, bottom: 8 })
// 状态指示灯
Row() {
Circle()
.width(8)
.height(8)
.fill(this.statusEffects.get(node.status)?.color || '#FFFFFF')
.animation({
duration: 1000,
curve: Curve.EaseInOut,
iterations: this.statusEffects.get(node.status)?.pulse ? -1 : 0,
playMode: PlayMode.Alternate
})
.scale({ x: 1.3, y: 1.3 })
}
.justifyContent(FlexAlign.Center)
.width('100%')
}
.width(100)
.height(100)
.backgroundColor('rgba(30, 30, 40, 0.9)')
.border({
width: 2,
color: this.selectedNodeId === node.id ? this.nodeColors.get(node.type) : 'rgba(255,255,255,0.2)'
})
.borderRadius(16)
.shadow({
radius: 10,
color: this.nodeColors.get(node.type),
offsetX: 0,
offsetY: 4
})
.position({ x: node.x, y: node.y })
.onClick(() => {
this.selectedNodeId = node.id;
AppStorage.setOrCreate('selected_node', node);
})
.gesture(
LongPressGesture({ duration: 300 })
.onAction(() => {
// 长按打开属性面板
AppStorage.setOrCreate('window_action', 'open_properties');
AppStorage.setOrCreate('selected_node', node);
})
)
}
}
private getNodeGlowOpacity(node: AgentNode): number {
if (node.status === 'running') return 0.6;
if (node.status === 'success') return 0.4;
if (node.status === 'error') return 0.5;
return 0.2;
}
private getNodeIcon(type: HMAFNodeType): Resource {
switch (type) {
case HMAFNodeType.LLM: return $r('app.media.ic_llm');
case HMAFNodeType.TOOL: return $r('app.media.ic_tool');
case HMAFNodeType.CONDITION: return $r('app.media.ic_condition');
case HMAFNodeType.LOOP: return $r('app.media.ic_loop');
case HMAFNodeType.OUTPUT: return $r('app.media.ic_output');
default: return $r('app.media.ic_node');
}
}
private drawEdges(context: CanvasRenderingContext2D): void {
context.strokeStyle = 'rgba(123, 97, 255, 0.6)';
context.lineWidth = 2;
context.setLineDash([5, 5]);
this.edges.forEach(edge => {
const fromNode = this.nodes.find(n => n.id === edge.from);
const toNode = this.nodes.find(n => n.id === edge.to);
if (!fromNode || !toNode) return;
// 绘制贝塞尔曲线连线
const startX = fromNode.x + 100;
const startY = fromNode.y + 50;
const endX = toNode.x;
const endY = toNode.y + 50;
const cpX = (startX + endX) / 2;
const cpY = startY;
context.beginPath();
context.moveTo(startX, startY);
context.quadraticCurveTo(cpX, cpY, endX, endY);
context.stroke();
// 绘制连线标签
if (edge.label) {
context.fillStyle = 'rgba(255,255,255,0.8)';
context.font = '12px sans-serif';
context.fillText(edge.label, cpX - 20, cpY - 10);
}
});
}
}
代码亮点:
- 节点类型光效:每种节点类型(LLM/工具/条件/循环/输出)拥有专属光色,从背景光晕到边框阴影统一主题
- 状态呼吸灯:节点运行中时绿色光晕脉冲呼吸,错误时红色脉冲,成功时稳定绿光,无需查看日志即可掌握状态
- 贝塞尔连线:使用Canvas绘制流畅的二次贝塞尔曲线,配合虚线流动效果,呈现"数据流"视觉隐喻
- 长按属性:长按节点自动打开浮动属性面板,符合PC端右键/长按的交互习惯
5.4 悬浮编排导航(FloatNavigation.ets)
// entry/src/main/ets/components/FloatNavigation.ets
import { HdsTabs, HdsTabItem } from '@kit.UIDesignKit';
export enum TransparencyLevel {
STRONG = 0.85,
BALANCED = 0.70,
WEAK = 0.55
}
@Component
export struct FloatNavigation {
@State currentMode: string = 'LLM';
@State transparency: number = TransparencyLevel.BALANCED;
@State isExpanded: boolean = false;
@State avoidHeight: number = 0;
// 编排模式配置
private modes: HdsTabItem[] = [
{ icon: $r('app.media.ic_llm'), label: 'LLM', badge: 0 },
{ icon: $r('app.media.ic_workflow'), label: '工作流', badge: 0 },
{ icon: $r('app.media.ic_a2a'), label: 'A2A', badge: 0 },
{ icon: $r('app.media.ic_openclaw'), label: 'OpenClaw', badge: 2 }
];
aboutToAppear(): void {
// 获取底部安全区高度
let windowInstance = window.getLastWindow(getContext(this));
windowInstance.then((win) => {
let avoidArea = win.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR);
this.avoidHeight = avoidArea.bottomRect.height;
});
}
build() {
Stack({ alignContent: Alignment.Bottom }) {
// 悬浮导航主体
Column() {
HdsTabs({
items: this.modes,
selectedIndex: this.getModeIndex(),
onSelect: (index: number) => {
this.currentMode = this.modes[index].label === 'LLM' ? 'LLM' :
this.modes[index].label === '工作流' ? 'Workflow' :
this.modes[index].label === 'A2A' ? 'A2A' : 'OpenClaw';
AppStorage.setOrCreate('current_mode', this.currentMode);
},
// 玻璃拟态背景
backgroundStyle: {
blurStyle: BlurStyle.REGULAR,
backgroundColor: `rgba(20, 20, 30, ${this.transparency})`,
borderRadius: 24
},
// 选中指示器光效
indicatorStyle: {
color: this.getModeColor(),
height: 3,
width: 24,
borderRadius: 2
}
})
.height(56)
.width('96%')
.margin({ bottom: 12 })
// 透明度调节条(展开时显示)
if (this.isExpanded) {
Row() {
Text('透明度').fontSize(12).fontColor('rgba(255,255,255,0.6)')
Slider({
value: this.transparency * 100,
min: 55,
max: 85,
step: 15
})
.width(200)
.onChange((value: number) => {
this.transparency = value / 100;
})
}
.width('96%')
.height(40)
.backgroundColor('rgba(20, 20, 30, 0.8)')
.borderRadius(16)
.justifyContent(FlexAlign.SpaceBetween)
.padding({ left: 16, right: 16 })
.animation({
duration: 200,
curve: Curve.EaseInOut
})
}
}
.width('100%')
.padding({ bottom: this.avoidHeight + 12 })
}
.width('100%')
.height('100%')
.pointerEvents(PointerEvents.BoxNone) // 允许点击穿透到画布
}
private getModeIndex(): number {
switch (this.currentMode) {
case 'LLM': return 0;
case 'Workflow': return 1;
case 'A2A': return 2;
case 'OpenClaw': return 3;
default: return 0;
}
}
private getModeColor(): string {
switch (this.currentMode) {
case 'LLM': return '#7B61FF';
case 'Workflow': return '#00B4D8';
case 'A2A': return '#00C9A7';
case 'OpenClaw': return '#FF6B9D';
default: return '#7B61FF';
}
}
}
代码亮点:
- 玻璃拟态导航:
BlurStyle.REGULAR配合动态透明度,实现悬浮于画布之上的玻璃质感 - 模式徽章:OpenClaw模式显示数字徽章,提示有新插件可用
- 透明度三档调节:强(85%)/平衡(70%)/弱(55%),通过Slider实时调节
- 点击穿透:
pointerEvents(BoxNone)确保导航不遮挡画布操作,鼠标可穿透到下层节点
5.5 多窗口光效同步管理器(WindowManager.ets)
// entry/src/main/ets/utils/WindowManager.ets
import { window } from '@kit.ArkUI';
export class WindowManager {
private static instance: WindowManager;
private subWindows: Map<string, window.Window> = new Map();
private themeColor: string = '#7B61FF';
static getInstance(): WindowManager {
if (!WindowManager.instance) {
WindowManager.instance = new WindowManager();
}
return WindowManager.instance;
}
// 同步全局光效主题色
syncGlobalLightEffect(color: string): void {
this.themeColor = color;
// 广播到所有子窗口
this.subWindows.forEach((win, name) => {
win.setWindowBackgroundColor(this.hexToRgba(color, 0.05));
});
}
// 打开属性面板窗口
async openPropertiesWindow(): Promise<void> {
if (this.subWindows.has('properties')) {
await this.subWindows.get('properties')?.show();
return;
}
let mainWindow = await window.getLastWindow(getContext());
let subWindow = await window.createSubWindow(getContext(), 'properties');
await subWindow.moveWindowTo(1200, 100);
await subWindow.resize(320, 600);
await subWindow.setWindowBackgroundColor(this.hexToRgba(this.themeColor, 0.05));
await subWindow.setWindowCornerRadius(16);
await subWindow.setWindowShadow({
radius: 20,
color: this.themeColor,
offsetX: 0,
offsetY: 8
});
await subWindow.loadContent('pages/PropertiesPage');
await subWindow.show();
this.subWindows.set('properties', subWindow);
}
// 打开预览窗口
async openPreviewWindow(): Promise<void> {
if (this.subWindows.has('preview')) {
await this.subWindows.get('preview')?.show();
return;
}
let subWindow = await window.createSubWindow(getContext(), 'preview');
await subWindow.moveWindowTo(200, 700);
await subWindow.resize(600, 400);
await subWindow.setWindowBackgroundColor('#0a0a0f');
await subWindow.setWindowCornerRadius(16);
await subWindow.setWindowShadow({
radius: 20,
color: this.themeColor,
offsetX: 0,
offsetY: 8
});
await subWindow.loadContent('pages/PreviewPage');
await subWindow.show();
this.subWindows.set('preview', subWindow);
}
// 打开调试控制台窗口
async openConsoleWindow(): Promise<void> {
if (this.subWindows.has('console')) {
await this.subWindows.get('console')?.show();
return;
}
let subWindow = await window.createSubWindow(getContext(), 'console');
await subWindow.moveWindowTo(800, 700);
await subWindow.resize(500, 300);
await subWindow.setWindowBackgroundColor('#0d0d12');
await subWindow.setWindowCornerRadius(12);
await subWindow.setWindowShadow({
radius: 15,
color: '#00E676',
offsetX: 0,
offsetY: 6
});
await subWindow.loadContent('pages/ConsolePage');
await subWindow.show();
this.subWindows.set('console', subWindow);
}
private hexToRgba(hex: string, alpha: number): string {
const r = parseInt(hex.slice(1, 3), 16);
const g = parseInt(hex.slice(3, 5), 16);
const b = parseInt(hex.slice(5, 7), 16);
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
}
}
代码亮点:
- 子窗口独立生命周期:每个浮动窗口(属性/预览/控制台)独立管理,支持多次打开/关闭
- 光效主题同步:
syncGlobalLightEffect将主窗口主题色广播到所有子窗口,实现跨窗口光效联动 - 差异化阴影:属性面板跟随主色调、控制台使用绿色阴影(日志主题),视觉区分清晰
- 圆角与阴影:所有子窗口统一16px圆角+动态阴影,保持设计语言一致性
5.6 属性面板窗口(PropertiesPage.ets)
// entry/src/main/ets/pages/PropertiesPage.ets
@Component
struct PropertiesPage {
@State selectedNode: AgentNode | null = null;
@State themeColor: string = '#7B61FF';
aboutToAppear(): void {
AppStorage.watch('selected_node', (node: AgentNode) => {
this.selectedNode = node;
});
AppStorage.watch('current_mode', (mode: string) => {
this.themeColor = this.getModeColor(mode);
});
}
private getModeColor(mode: string): string {
const colors: Map<string, string> = new Map([
['LLM', '#7B61FF'],
['Workflow', '#00B4D8'],
['A2A', '#00C9A7'],
['OpenClaw', '#FF6B9D']
]);
return colors.get(mode) || '#7B61FF';
}
build() {
Column() {
// 面板标题栏(带光效)
Row() {
Text('节点属性')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor('#FFFFFF')
Circle()
.width(10)
.height(10)
.fill(this.themeColor)
.shadow({ radius: 8, color: this.themeColor })
}
.width('100%')
.height(48)
.padding({ left: 16, right: 16 })
.justifyContent(FlexAlign.SpaceBetween)
.backgroundColor('rgba(255,255,255,0.05)')
.border({ width: { bottom: 1 }, color: 'rgba(255,255,255,0.1)' })
// 节点配置表单
if (this.selectedNode) {
Scroll() {
Column({ space: 16 }) {
// 节点类型标识
Row() {
Image(this.getNodeIcon(this.selectedNode.type))
.width(24)
.height(24)
.fillColor(this.themeColor)
Text(this.selectedNode.type)
.fontSize(14)
.fontColor(this.themeColor)
.margin({ left: 8 })
}
.width('100%')
.padding(12)
.backgroundColor('rgba(255,255,255,0.03)')
.borderRadius(8)
// 节点名称
Column({ space: 4 }) {
Text('节点名称').fontSize(12).fontColor('rgba(255,255,255,0.6)')
TextInput({ text: this.selectedNode.label })
.width('100%')
.height(40)
.backgroundColor('rgba(255,255,255,0.05)')
.fontColor('#FFFFFF')
.borderRadius(8)
}
// 配置参数(根据节点类型动态渲染)
this.buildNodeConfig(this.selectedNode)
// 操作按钮
Row({ space: 12 }) {
Button('应用')
.width(100)
.height(36)
.backgroundColor(this.themeColor)
.fontColor('#FFFFFF')
.onClick(() => {
AppStorage.setOrCreate('agent_action', 'update_node');
})
Button('删除')
.width(100)
.height(36)
.backgroundColor('rgba(255, 23, 68, 0.2)')
.fontColor('#FF1744')
.onClick(() => {
AppStorage.setOrCreate('agent_action', 'delete_node');
})
}
.width('100%')
.justifyContent(FlexAlign.Center)
.margin({ top: 20 })
}
.width('100%')
.padding(16)
}
.layoutWeight(1)
} else {
// 未选中节点提示
Column() {
Image($r('app.media.ic_empty'))
.width(64)
.height(64)
.opacity(0.3)
Text('在画布中选择节点以编辑属性')
.fontSize(14)
.fontColor('rgba(255,255,255,0.4)')
.margin({ top: 12 })
}
.width('100%')
.layoutWeight(1)
.justifyContent(FlexAlign.Center)
}
}
.width('100%')
.height('100%')
.backgroundColor('rgba(15, 15, 25, 0.95)')
.borderRadius(16)
}
@Builder
buildNodeConfig(node: AgentNode): void {
switch (node.type) {
case HMAFNodeType.LLM:
this.buildLLMConfig(node);
break;
case HMAFNodeType.TOOL:
this.buildToolConfig(node);
break;
default:
this.buildGenericConfig(node);
}
}
@Builder
buildLLMConfig(node: AgentNode): void {
Column({ space: 12 }) {
Column({ space: 4 }) {
Text('模型选择').fontSize(12).fontColor('rgba(255,255,255,0.6)')
Select([
{ value: 'gpt-4o', icon: $r('app.media.ic_openai') },
{ value: 'claude-3-5', icon: $r('app.media.ic_anthropic') },
{ value: 'qwen-2-5', icon: $r('app.media.ic_qwen') }
])
.width('100%')
.height(40)
.selected(node.config.model || 'gpt-4o')
}
Column({ space: 4 }) {
Text('温度').fontSize(12).fontColor('rgba(255,255,255,0.6)')
Slider({ value: node.config.temperature || 0.7, min: 0, max: 2, step: 0.1 })
.width('100%')
.trackColor(this.themeColor)
}
Column({ space: 4 }) {
Text('系统提示词').fontSize(12).fontColor('rgba(255,255,255,0.6)')
TextArea({ text: node.config.systemPrompt || '' })
.width('100%')
.height(120)
.backgroundColor('rgba(255,255,255,0.05)')
.fontColor('#FFFFFF')
.borderRadius(8)
}
}
}
@Builder
buildToolConfig(node: AgentNode): void {
Column({ space: 12 }) {
Column({ space: 4 }) {
Text('工具类型').fontSize(12).fontColor('rgba(255,255,255,0.6)')
Select([
{ value: 'web_search', icon: $r('app.media.ic_search') },
{ value: 'code_executor', icon: $r('app.media.ic_code') },
{ value: 'file_reader', icon: $r('app.media.ic_file') }
])
.width('100%')
.height(40)
.selected(node.config.tool || 'web_search')
}
}
}
private getNodeIcon(type: HMAFNodeType): Resource {
// 同AgentCanvas中的实现
return $r('app.media.ic_node');
}
}
5.7 调试控制台窗口(ConsolePage.ets)
// entry/src/main/ets/pages/ConsolePage.ets
interface LogEntry {
timestamp: string;
level: 'info' | 'warn' | 'error' | 'debug';
message: string;
nodeId?: string;
}
@Component
struct ConsolePage {
@State logs: LogEntry[] = [];
@State filterLevel: string = 'all';
@State autoScroll: boolean = true;
// 日志级别颜色
private levelColors: Map<string, string> = new Map([
['info', '#4CC9F0'],
['warn', '#FF9F1C'],
['error', '#FF1744'],
['debug', '#9C27B0']
]);
aboutToAppear(): void {
// 监听全局日志
AppStorage.watch('agent_log', (log: LogEntry) => {
this.logs.push(log);
if (this.logs.length > 1000) {
this.logs.shift(); // 限制日志数量
}
});
}
build() {
Column() {
// 控制台标题栏
Row() {
Text('调试控制台')
.fontSize(14)
.fontWeight(FontWeight.Medium)
.fontColor('#00E676')
Row({ space: 8 }) {
// 日志级别筛选
Select([
{ value: 'all' },
{ value: 'info' },
{ value: 'warn' },
{ value: 'error' },
{ value: 'debug' }
])
.width(100)
.height(28)
.selected(this.filterLevel)
.onSelect((index: number) => {
this.filterLevel = ['all', 'info', 'warn', 'error', 'debug'][index];
})
// 自动滚动开关
Toggle({ type: ToggleType.Checkbox, isOn: this.autoScroll })
.selectedColor('#00E676')
.onChange((isOn: boolean) => {
this.autoScroll = isOn;
})
}
}
.width('100%')
.height(36)
.padding({ left: 12, right: 12 })
.justifyContent(FlexAlign.SpaceBetween)
.backgroundColor('rgba(0, 230, 118, 0.05)')
.border({ width: { bottom: 1 }, color: 'rgba(0, 230, 118, 0.2)' })
// 日志列表
List({ space: 2 }) {
ForEach(this.getFilteredLogs(), (log: LogEntry, index: number) => {
ListItem() {
Row({ space: 8 }) {
// 时间戳
Text(log.timestamp)
.fontSize(10)
.fontColor('rgba(255,255,255,0.4)')
.width(80)
// 级别标识
Text(log.level.toUpperCase())
.fontSize(10)
.fontWeight(FontWeight.Bold)
.fontColor(this.levelColors.get(log.level) || '#FFFFFF')
.width(50)
.textAlign(TextAlign.Center)
// 节点标识
if (log.nodeId) {
Text(`[${log.nodeId}]`)
.fontSize(10)
.fontColor('rgba(255,255,255,0.5)')
.width(80)
}
// 日志内容
Text(log.message)
.fontSize(12)
.fontColor('#FFFFFF')
.layoutWeight(1)
.maxLines(3)
.textOverflow({ overflow: TextOverflow.Ellipsis })
}
.width('100%')
.padding({ left: 12, right: 12, top: 6, bottom: 6 })
.backgroundColor(index % 2 === 0 ? 'rgba(255,255,255,0.02)' : 'transparent')
}
}, (log: LogEntry, index: number) => `${log.timestamp}-${index}`)
}
.width('100%')
.layoutWeight(1)
.edgeEffect(EdgeEffect.Spring)
.scrollBar(BarState.Auto)
}
.width('100%')
.height('100%')
.backgroundColor('rgba(13, 13, 18, 0.98)')
.borderRadius(12)
}
private getFilteredLogs(): LogEntry[] {
if (this.filterLevel === 'all') return this.logs;
return this.logs.filter(log => log.level === this.filterLevel);
}
}
5.8 主页面集成(EditorPage.ets)
// entry/src/main/ets/pages/EditorPage.ets
import { ImmersiveTitleBar } from '../components/ImmersiveTitleBar';
import { AgentCanvas } from '../components/AgentCanvas';
import { FloatNavigation } from '../components/FloatNavigation';
import { WindowManager } from '../utils/WindowManager';
@Entry
@Component
struct EditorPage {
@State currentMode: string = 'LLM';
@State themeColor: string = '#7B61FF';
@State lightIntensity: number = 0.6;
aboutToAppear(): void {
// 监听编排模式变化
AppStorage.watch('current_mode', (mode: string) => {
this.currentMode = mode;
this.themeColor = this.getModeColor(mode);
WindowManager.getInstance().syncGlobalLightEffect(this.themeColor);
});
// 监听窗口操作
AppStorage.watch('window_action', (action: string) => {
switch (action) {
case 'open_properties':
WindowManager.getInstance().openPropertiesWindow();
break;
case 'open_preview':
WindowManager.getInstance().openPreviewWindow();
break;
case 'open_console':
WindowManager.getInstance().openConsoleWindow();
break;
}
// 重置操作
AppStorage.setOrCreate('window_action', '');
});
}
private getModeColor(mode: string): string {
const colors: Map<string, string> = new Map([
['LLM', '#7B61FF'],
['Workflow', '#00B4D8'],
['A2A', '#00C9A7'],
['OpenClaw', '#FF6B9D']
]);
return colors.get(mode) || '#7B61FF';
}
build() {
Stack() {
// 第一层:动态环境光背景
this.buildAmbientLightLayer()
// 第二层:内容层
Column() {
// 沉浸光感标题栏
ImmersiveTitleBar({ currentMode: this.currentMode })
// 智能体编排画布
AgentCanvas()
.layoutWeight(1)
}
.width('100%')
.height('100%')
// 第三层:悬浮编排导航
FloatNavigation()
}
.width('100%')
.height('100%')
.backgroundColor('#0a0a0f')
.expandSafeArea(
[SafeAreaType.SYSTEM],
[SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM, SafeAreaEdge.START, SafeAreaEdge.END]
)
}
@Builder
buildAmbientLightLayer(): void {
Column() {
// 主光晕 - 随模式变色
Column()
.width(600)
.height(600)
.backgroundColor(this.themeColor)
.blur(200)
.opacity(this.lightIntensity * 0.3)
.position({ x: '50%', y: '30%' })
.anchor('50%')
.animation({
duration: 8000,
curve: Curve.EaseInOut,
iterations: -1,
playMode: PlayMode.Alternate
})
.scale({ x: 1.5, y: 1.5 })
// 底部反射
Column()
.width('100%')
.height(300)
.backgroundColor(this.themeColor)
.opacity(this.lightIntensity * 0.08)
.blur(150)
.position({ x: 0, y: '70%' })
.linearGradient({
direction: GradientDirection.Top,
colors: [
[this.themeColor, 0.0],
['transparent', 1.0]
]
})
.animation({
duration: 10000,
curve: Curve.EaseInOut,
iterations: -1,
playMode: PlayMode.Alternate
})
// 粒子光点(模拟数据流)
ForEach([1, 2, 3, 4, 5], (index: number) => {
Circle()
.width(4)
.height(4)
.backgroundColor(this.themeColor)
.opacity(0.6)
.position({
x: `${20 + index * 15}%`,
y: `${30 + index * 10}%`
})
.animation({
duration: 3000 + index * 500,
curve: Curve.EaseInOut,
iterations: -1,
playMode: PlayMode.Alternate
})
.translate({ y: -20 })
})
}
.width('100%')
.height('100%')
.backgroundColor('#050508')
}
}
代码亮点:
- 三层架构:环境光层 → 内容层 → 悬浮导航层,层次分明
- 模式感知环境光:切换编排模式时,整个背景光晕颜色随之变化,LLM模式紫色、工作流模式蓝色、A2A模式青色、OpenClaw模式粉色
- 呼吸动画:主光晕8秒循环呼吸、底部反射10秒循环,营造"活"的界面氛围
- 数据流粒子:5个光点模拟数据在节点间流动,增强编排的动态感
- 安全区扩展:
expandSafeArea让内容延伸至所有屏幕边缘,实现真正的全屏沉浸
六、HMAF智能体编排引擎集成
6.1 创建智能体会话
// entry/src/main/ets/engine/AgentEngine.ets
import { hmaf } from '@kit.AgentFrameworkKit';
import { intents } from '@kit.IntentsKit';
export class AgentEngine {
private session: hmaf.AgentSession | null = null;
private intentEngine: intents.IntentEngine | null = null;
async initialize(mode: 'LLM' | 'Workflow' | 'A2A' | 'OpenClaw'): Promise<void> {
// 创建智能体会话
this.session = await hmaf.createAgentSession({
mode: mode === 'LLM' ? hmaf.AgentMode.LLM :
mode === 'Workflow' ? hmaf.AgentMode.WORKFLOW :
mode === 'A2A' ? hmaf.AgentMode.A2A : hmaf.AgentMode.OPENCLAW,
enableDistributed: true, // 启用分布式能力
maxConcurrentAgents: 10
});
// 创建意图引擎
this.intentEngine = await intents.createIntentEngine({
supportedDomains: ['agent.orchestration', 'node.creation', 'edge.connection'],
confidenceThreshold: 0.8
});
// 监听编排事件
this.session.on('taskCompleted', (result) => {
AppStorage.setOrCreate('agent_log', {
timestamp: new Date().toISOString(),
level: 'info',
message: `任务完成: ${result.taskId}`,
nodeId: result.nodeId
});
});
this.session.on('taskFailed', (error) => {
AppStorage.setOrCreate('agent_log', {
timestamp: new Date().toISOString(),
level: 'error',
message: `任务失败: ${error.message}`,
nodeId: error.nodeId
});
});
}
// 执行编排
async executeWorkflow(nodes: AgentNode[], edges: AgentEdge[]): Promise<void> {
if (!this.session) return;
// 构建HMAF任务图
const taskGraph = this.buildTaskGraph(nodes, edges);
// 提交编排任务
await this.session.sendTask({
targetAgent: 'orchestrator',
taskType: hmaf.TaskType.WORKFLOW_EXECUTION,
payload: taskGraph
});
}
private buildTaskGraph(nodes: AgentNode[], edges: AgentEdge[]): any {
return {
nodes: nodes.map(n => ({
id: n.id,
type: n.type,
config: n.config,
agentId: `agent_${n.id}`
})),
edges: edges.map(e => ({
from: e.from,
to: e.to,
condition: e.label
}))
};
}
}
6.2 意图驱动的智能编排
// entry/src/main/ets/engine/IntentOrchestrator.ets
export class IntentOrchestrator {
private engine: AgentEngine;
constructor() {
this.engine = new AgentEngine();
}
// 解析用户拖拽意图
async parseDragIntent(
startNode: AgentNode,
endNode: AgentNode,
gestureType: string
): Promise<string> {
const intent = await this.engine.intentEngine?.process({
action: gestureType === 'long_press' ? 'create_connection' : 'move_node',
entities: [
{ type: 'node', value: startNode.id },
{ type: 'node', value: endNode.id },
{ type: 'node_type', value: startNode.type }
]
});
if (intent?.confidence && intent.confidence > 0.8) {
return intent.action;
}
return 'unknown';
}
// 根据意图自动调整光效
async applyIntentLightEffect(intent: string): Promise<void> {
switch (intent) {
case 'create_connection':
// 连线时触发流光动画
AppStorage.setOrCreate('light_effect', 'connection_flow');
break;
case 'delete_node':
// 删除时红色闪烁警示
AppStorage.setOrCreate('light_effect', 'delete_warning');
break;
case 'run_workflow':
// 运行时全屏绿色脉冲
AppStorage.setOrCreate('light_effect', 'running_pulse');
break;
}
}
}

七、关键技术总结
7.1 HMAF可视化编排开发清单
| 技术点 | API/方法 | 应用场景 |
|---|---|---|
| 智能体会话创建 | hmaf.createAgentSession({ mode: MULTI_AGENT }) |
多智能体协作编排 |
| 意图解析 | intents.createIntentEngine({ supportedDomains }) |
用户拖拽意图理解 |
| 任务分发 | hmafSession.sendTask({ targetAgent, taskType }) |
智能体间编排任务调度 |
| 状态监听 | AppStorage 全局状态回调 |
跨组件编排状态同步 |
| 分布式协同 | enableDistributed: true |
多设备编排协作 |
| 四种编排模式 | LLM/Workflow/A2A/OpenClaw |
不同场景模式切换 |
7.2 沉浸光感实现清单
| 技术点 | API/方法 | 应用场景 |
|---|---|---|
| 系统材质效果 | systemMaterialEffect: SystemMaterialEffect.IMMERSIVE |
HdsNavigation标题栏 |
| 背景模糊 | backgroundBlurStyle(BlurStyle.REGULAR) |
悬浮导航玻璃拟态 |
| 背景滤镜 | backdropFilter($r('sys.blur.20')) |
精细模糊控制 |
| 安全区扩展 | expandSafeArea([SafeAreaType.SYSTEM], [...]) |
全屏沉浸布局 |
| 窗口沉浸 | setWindowLayoutFullScreen(true) |
无边框模式 |
| 光效动画 | animation({ duration, iterations: -1 }) |
呼吸灯背景 |
| 动态透明度 | backgroundOpacity |
焦点感知降级 |
7.3 悬浮导航适配要点
- 安全区避让:通过
getWindowAvoidArea获取底部导航指示器高度,内容区域动态预留空间 - 悬浮层级设计:导航栏脱离底边,使用
margin({ left: '2%', right: '2%', bottom: avoidHeight + 12 })实现四周留白 - 透明度动态调节:支持强/平衡/弱三档,通过Slider或预设按钮实时调整
- PC交互优化:支持鼠标悬停预览、中键关闭、右键上下文菜单
7.4 PC端多窗口光效协同
- 主窗口:全屏沉浸,环境光背景延伸至所有安全区边缘
- 浮动工具窗口:置顶、圆角、阴影,跟随主窗口移动
- 光效同步:通过
AppStorage全局状态实现跨窗口主题色联动 - 焦点感知:窗口激活时边缘发光增强,失活时自动降低光效强度
八、调试与性能优化
8.1 真机调试建议
- 光效真机验证:玻璃拟态效果在模拟器上可能显示异常,建议在支持HarmonyOS 6的MateBook真机上测试
- 多窗口测试:验证子窗口在分屏、悬浮模式下的位置同步与光效一致性
- 手势冲突排查:确保画布拖拽手势与系统导航手势不冲突
8.2 性能优化策略
- 光效降级:在低端设备上自动降低模糊半径和动画帧率
- 节点懒加载:画布节点超过50个时启用虚拟列表,只渲染可视区域节点
- 日志限流:调试控制台限制最大1000条日志,防止内存溢出
- 子窗口复用:已创建的子窗口隐藏而非销毁,避免重复创建开销
九、总结与展望
本文基于HarmonyOS 6(API 23)的悬浮导航与沉浸光感特性,完整实战了一款面向PC端的"智流工坊"低代码智能体编排平台。核心创新点总结:
-
节点类型光效系统:每种智能体节点(LLM/工具/条件/循环/输出)拥有专属光色,从背景光晕到节点阴影形成统一的视觉语言,让编排者一眼识别节点类型与运行状态
-
悬浮编排导航:底部悬浮页签替代传统工具栏,玻璃拟态设计+三档透明度调节,在保持导航可达性的同时最大化画布编辑区域
-
HMAF可视化编排引擎:基于Agent Framework Kit构建拖拽式节点编排引擎,支持LLM/Workflow/A2A/OpenClaw四种模式无缝切换,通过Intents Kit实现意图驱动的智能编排
-
PC级多窗口协作:主画布窗口 + 浮动属性面板 + 浮动预览窗口 + 浮动调试控制台窗口的四层架构,通过WindowManager实现跨窗口光效联动与焦点感知,符合专业开发者的工作习惯
-
HDS系统材质深度应用:
systemMaterialEffect.IMMERSIVE为标题栏和导航组件带来物理光照级的光晕与反射效果,告别传统开发者工具的"工业灰"审美
未来扩展方向:
- 接入分布式软总线,实现跨设备智能体编排(手机扫码继续编排、平板作为扩展预览屏)
- 结合AI辅助编排:基于当前编排上下文,AI建议以光效形式在背景层呈现(如绿色光晕表示高置信度建议)
- 探索Face AR能力:通过摄像头捕捉开发者注意力状态,自动调节光效强度(专注时增强、疲劳时减弱)
- 插件化架构:支持第三方智能体插件市场,让开发者社区贡献更多节点类型与光效主题
转载自:https://blog.csdn.net/u014727709/article/details/162388955
欢迎 👍点赞✍评论⭐收藏,欢迎指正
更多推荐




所有评论(0)