HarmonyOS 6 悬浮导航 + 沉浸光感:打造鸿蒙智能体驱动的沉浸式编程学习伴侣
学习HarmonyOS开发的过程中,开发者常常面临这样的困境:看着官方文档写代码,却在@State和@Prop的区别上反复踩坑;跟着教程实现动画,却不知道animateTo和animation的适用场景;想查询某个API的用法,却要在IDE和浏览器之间来回切换。HarmonyOS 6(API 23)带来的悬浮导航(Floating Navigation)和沉浸光感(Immersive Lighti

每日一句正能量
世间的纷扰从不会停歇,但内心的回应却可以选择。
外界的噪音、他人的情绪、突发的事件,我们无法控制它们是否发生,但我们永远有权利决定“如何回应”。
一、前言:当AI导师常驻屏幕边缘
学习HarmonyOS开发的过程中,开发者常常面临这样的困境:看着官方文档写代码,却在@State和@Prop的区别上反复踩坑;跟着教程实现动画,却不知道animateTo和animation的适用场景;想查询某个API的用法,却要在IDE和浏览器之间来回切换。
HarmonyOS 6(API 23)带来的悬浮导航(Floating Navigation)和沉浸光感(Immersive Lighting)能力,让我们有机会打造一个常驻屏幕边缘的AI编程学习伴侣——它像一位耐心的导师,在你编码时静静悬浮在屏幕角落,当你遇到困惑时随时唤出;它通过光效感知你的学习状态,在你连续犯错时温柔提醒,在你突破难点时为你喝彩。
核心创新点:
- 🎓 上下文感知教学:悬浮窗自动识别你正在编写的代码类型,主动推送相关知识点
- 💡 情绪光感反馈:通过设备边框光效颜色变化,反映你的学习状态(困惑/专注/突破)
- 🤖 多模态智能体:支持语音提问、代码截图识别、手势唤出三种交互方式
- 📚 知识图谱导航:将鸿蒙开发知识体系可视化,悬浮窗即知识地图
二、应用场景设计
2.1 场景一:API速查伴侣
当你在DevEco Studio中输入List时,悬浮胶囊自动识别你的意图,轻点展开即可看到List组件的完整API速查卡片,包括常用属性、事件和最佳实践,无需离开IDE。
2.2 场景二:错误即时诊断
代码编译报错"Property 'xxx' has no initializer and is not definitely assigned in the constructor",悬浮窗检测到错误后,边框泛起琥珀色光效,展开后智能体不仅解释错误原因,还给出鸿蒙特有的解决方案(如使用!非空断言或@Require装饰器)。
2.3 场景三:学习路径引导
作为鸿蒙新手,你不确定该先学ArkUI布局还是并发模型。智能体通过分析你的代码习惯,在悬浮窗中生成个性化的学习路径图,并用光效进度条展示当前学习进度。
三、技术架构
┌─────────────────────────────────────────────────────────────┐
│ HarmonyOS Programming Tutor Agent │
├─────────────┬─────────────┬─────────────┬───────────────────┤
│ 悬浮窗UI │ 沉浸光感 │ 智能体引擎 │ 知识图谱模块 │
│ FloatUI │ Lighting │ AI Engine │ KnowledgeGraph │
├─────────────┴─────────────┴─────────────┴───────────────────┤
│ 上下文感知层(Context Aware) │
│ 代码语义分析 │ 手势识别 │ 语音输入 │ 学习行为追踪 │
├─────────────────────────────────────────────────────────────┤
│ HarmonyOS 6 (API 23) 系统服务层 │
│ 悬浮导航 │ 光感服务 │ 智能体框架 │ 无障碍服务 │ 语音服务 │
└─────────────────────────────────────────────────────────────┘
四、核心代码实现
4.1 上下文感知引擎(ContextAwareEngine)
这是整个系统的"眼睛",通过无障碍服务获取当前IDE中的代码上下文,分析开发者正在做什么。
// engine/ContextAwareEngine.ets
import { accessibility } from '@kit.AccessibilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
export interface CodeContext {
currentFile: string; // 当前文件名
cursorPosition: Position; // 光标位置
surroundingCode: string; // 光标前后代码
detectedIntent: CodingIntent; // 推断的编码意图
complexity: number; // 当前代码复杂度 0-100
}
export enum CodingIntent {
LAYOUT_DESIGN = 'layout_design', // 正在设计UI布局
STATE_MANAGEMENT = 'state_management', // 正在处理状态
ANIMATION = 'animation', // 正在实现动画
NETWORKING = 'networking', // 正在处理网络请求
NAVIGATION = 'navigation', // 正在处理页面路由
LIFECYCLE = 'lifecycle', // 正在处理生命周期
UNKNOWN = 'unknown'
}
export class ContextAwareEngine {
private accessibilityInstance: accessibility.Accessibility | null = null;
private lastContext: CodeContext | null = null;
private intentCallbacks: Array<(context: CodeContext) => void> = [];
/**
* 初始化无障碍服务监听
* 亮点:通过无障碍API获取DevEco Studio中的代码上下文,无需修改IDE
*/
async init(): Promise<void> {
try {
// 申请无障碍服务权限(用户手动授权)
const granted = await accessibility.requestAccessibilityPermission();
if (!granted) {
console.warn('[Context] 无障碍权限未授予,上下文感知能力受限');
return;
}
// 注册窗口内容变化监听
this.accessibilityInstance = accessibility.getAccessibility();
this.accessibilityInstance.on('windowContentChange', (event) => {
this.handleWindowChange(event);
});
console.info('[Context] 上下文感知引擎初始化完成');
} catch (err) {
console.error(`[Context] 初始化失败: ${JSON.stringify(err)}`);
}
}
/**
* 分析代码上下文,推断编码意图
* 策略:基于代码片段的关键词匹配 + 语义分析
*/
private analyzeIntent(code: string, fileName: string): CodingIntent {
const lowerCode = code.toLowerCase();
const ext = fileName.split('.').pop()?.toLowerCase();
// 根据文件类型快速判断
if (ext === 'ets') {
// ArkUI页面文件
if (lowerCode.includes('@state') || lowerCode.includes('@prop') ||
lowerCode.includes('@provide') || lowerCode.includes('@consume')) {
return CodingIntent.STATE_MANAGEMENT;
}
if (lowerCode.includes('animate') || lowerCode.includes('transition') ||
lowerCode.includes('animation')) {
return CodingIntent.ANIMATION;
}
if (lowerCode.includes('column') || lowerCode.includes('row') ||
lowerCode.includes('flex') || lowerCode.includes('grid') ||
lowerCode.includes('stack')) {
return CodingIntent.LAYOUT_DESIGN;
}
if (lowerCode.includes('router') || lowerCode.includes('navdestination') ||
lowerCode.includes('navigation')) {
return CodingIntent.NAVIGATION;
}
if (lowerCode.includes('abouttoappear') || lowerCode.includes('abouttodisappear') ||
lowerCode.includes('onpageShow')) {
return CodingIntent.LIFECYCLE;
}
}
if (ext === 'ts' && (lowerCode.includes('http') || lowerCode.includes('axios') ||
lowerCode.includes('rdb') || lowerCode.includes('preferences'))) {
return CodingIntent.NETWORKING;
}
return CodingIntent.UNKNOWN;
}
/**
* 计算当前代码复杂度
* 用于判断开发者是否可能遇到困难
*/
private calculateComplexity(code: string): number {
let score = 0;
// 嵌套层级
const nestDepth = (code.match(/{/g) || []).length;
score += Math.min(nestDepth * 5, 30);
// 装饰器数量
const decoratorCount = (code.match(/@\w+/g) || []).length;
score += Math.min(decoratorCount * 3, 15);
// 异步操作
if (code.includes('async') || code.includes('Promise') || code.includes('await')) {
score += 10;
}
// 并发相关
if (code.includes('TaskPool') || code.includes('Worker') || code.includes('concurrent')) {
score += 15;
}
// 代码长度
if (code.length > 500) score += 10;
return Math.min(score, 100);
}
private handleWindowChange(event: accessibility.AccessibilityEvent): void {
// 提取窗口中的文本内容(模拟实现)
const windowText = event.windowContent?.text || '';
// 解析当前文件信息
const fileMatch = windowText.match(/(\w+\.(ets|ts|json))/);
const currentFile = fileMatch ? fileMatch[1] : 'unknown';
// 提取光标附近代码(简化实现)
const surroundingCode = this.extractCodeAroundCursor(windowText);
const context: CodeContext = {
currentFile,
cursorPosition: { line: 0, column: 0 }, // 实际需通过更精细的解析获取
surroundingCode,
detectedIntent: this.analyzeIntent(surroundingCode, currentFile),
complexity: this.calculateComplexity(surroundingCode)
};
// 如果意图发生变化,通知订阅者
if (!this.lastContext || this.lastContext.detectedIntent !== context.detectedIntent) {
this.intentCallbacks.forEach(cb => cb(context));
}
this.lastContext = context;
}
private extractCodeAroundCursor(fullText: string): string {
// 简化:取最后300字符作为当前上下文
return fullText.slice(-300);
}
onIntentChange(callback: (context: CodeContext) => void): void {
this.intentCallbacks.push(callback);
}
getLastContext(): CodeContext | null {
return this.lastContext;
}
destroy(): void {
this.accessibilityInstance?.off('windowContentChange');
}
}
4.2 沉浸光感学习状态反馈(LearningLightController)
光效不仅是装饰,更是学习状态的"情绪晴雨表"。我们设计了四种核心光效模式,对应不同的学习场景。
// lighting/LearningLightController.ets
import { lighting } from '@kit.ArkUI';
export enum LearningState {
IDLE = 'idle', // 空闲:无操作
FOCUSED = 'focused', // 专注:正常编码
CONFUSED = 'confused', // 困惑:反复修改、报错
BREAKTHROUGH = 'breakthrough', // 突破:成功解决难题
GUIDING = 'guiding' // 引导:智能体正在讲解
}
export class LearningLightController {
private currentState: LearningState = LearningState.IDLE;
private confusionTimer: number = 0;
private lastErrorCount: number = 0;
private focusStartTime: number = 0;
/**
* 初始化学习状态光感
* 设计哲学:光效应成为开发者的"第六感",不干扰但能感知
*/
async init(): Promise<void> {
if (!lighting.isImmersiveLightSupported()) {
console.warn('[Light] 设备不支持沉浸光感');
return;
}
// 初始状态:柔和白色,表示就绪
await this.setLightEffect({
type: 'solid',
position: 'bottom_edge', // 仅底部边缘,减少干扰
color: '#E0E0E0',
brightness: 30,
duration: 0
});
console.info('[Light] 学习光感初始化完成');
}
/**
* 更新学习状态
* 核心逻辑:通过分析编码行为模式推断学习状态
*/
async updateState(context: {
intent: string;
complexity: number;
errorCount: number;
typingSpeed: number; // 打字速度(字符/分钟)
pauseDuration: number; // 停顿时间(秒)
deleteRate: number; // 删除率(0-1)
}): Promise<void> {
let newState = LearningState.FOCUSED;
// 困惑检测:高删除率 + 长时间停顿 + 报错增加
if (context.deleteRate > 0.3 && context.pauseDuration > 10) {
newState = LearningState.CONFUSED;
}
// 突破检测:从困惑状态恢复,且代码复杂度下降
if (this.currentState === LearningState.CONFUSED &&
context.errorCount < this.lastErrorCount &&
context.typingSpeed > 200) {
newState = LearningState.BREAKTHROUGH;
}
// 专注检测:稳定输入,低删除率
if (context.typingSpeed > 100 && context.deleteRate < 0.1 &&
context.pauseDuration < 3) {
newState = LearningState.FOCUSED;
}
// 状态变化时更新光效
if (newState !== this.currentState) {
await this.applyStateLighting(newState);
this.currentState = newState;
}
this.lastErrorCount = context.errorCount;
}
/**
* 应用状态对应的光效
* 每种状态都有独特的光效"签名"
*/
private async applyStateLighting(state: LearningState): Promise<void> {
const effects: Record<LearningState, lighting.LightEffect> = {
[LearningState.IDLE]: {
type: 'solid',
position: 'bottom_edge',
color: '#E0E0E0', // 柔和白
brightness: 20,
duration: 0
},
[LearningState.FOCUSED]: {
type: 'breathing',
position: 'bottom_edge',
color: '#00B0FF', // 科技蓝,呼吸节奏
brightness: 40,
duration: 0,
frequency: 3000 // 慢呼吸,3秒一周期
},
[LearningState.CONFUSED]: {
type: 'wave', // 波浪效果,表示思绪波动
position: 'all_edges',
color: '#FF9100', // 琥珀橙
brightness: 50,
duration: 0,
direction: 'alternate' // 来回波动
},
[LearningState.BREAKTHROUGH]: {
type: 'flashing',
position: 'all_edges',
color: '#76FF03', // 翠绿
brightness: 70,
duration: 3000,
flashCount: 5 // 闪烁5次庆祝
},
[LearningState.GUIDING]: {
type: 'chasing', // 追逐光效,表示引导中
position: 'all_edges',
color: '#E040FB', // 紫色
brightness: 45,
duration: 0,
speed: 'medium'
}
};
await lighting.setImmersiveLight(effects[state]);
console.info(`[Light] 学习状态切换: ${state}`);
}
/**
* 知识点掌握度光效反馈
* 当学习者掌握某个知识点时,以进度条形式展示
*/
async showMasteryProgress(mastery: number): Promise<void> {
// mastery: 0-100,掌握度百分比
const hue = Math.floor((mastery / 100) * 120); // 红(0) -> 绿(120)
const color = `hsl(${hue}, 100%, 50%)`;
await lighting.setImmersiveLight({
type: 'progress',
position: 'bottom_edge',
color: color,
brightness: 50,
duration: 2000,
progress: mastery / 100 // 光效填充比例
});
}
/**
* 错误提醒光效
* 检测到常见错误模式时的即时反馈
*/
async errorAlert(errorType: string): Promise<void> {
const errorColors: Record<string, string> = {
'null_pointer': '#FF1744', // 红:空指针
'type_mismatch': '#FFEA00', // 黄:类型不匹配
'async_await': '#FF9100', // 橙:异步问题
'lifecycle': '#D500F9' // 紫:生命周期
};
await lighting.setImmersiveLight({
type: 'flashing',
position: 'left_edge', // 左侧闪烁,不遮挡代码
color: errorColors[errorType] || '#FF1744',
brightness: 60,
duration: 1500,
flashCount: 2
});
}
async reset(): Promise<void> {
await lighting.resetImmersiveLight();
}
}
4.3 知识图谱悬浮窗(KnowledgeFloatWindow)
悬浮窗不仅是信息展示,更是知识导航的入口。我们设计了"胶囊-卡片-面板"三级展开体系。
// float/KnowledgeFloatWindow.ets
import { window } from '@kit.ArkUI';
import { emitter } from '@kit.BasicServicesKit';
export interface KnowledgeNode {
id: string;
title: string;
category: string;
difficulty: 'beginner' | 'intermediate' | 'advanced';
summary: string;
codeExample?: string;
relatedNodes: string[];
isMastered: boolean;
}
export class KnowledgeFloatWindow {
private floatWin: window.Window | null = null;
private currentLevel: 'capsule' | 'card' | 'panel' = 'capsule';
private currentIntent: string = '';
async create(): Promise<void> {
const option: window.WindowOption = {
name: 'KnowledgeTutor',
windowType: window.WindowType.TYPE_FLOAT,
ctx: getContext(this)
};
this.floatWin = await window.createWindow(getContext(this), option);
// 胶囊形态:仅显示当前学习领域图标
await this.floatWin.resize({ width: 80, height: 80 });
await this.floatWin.moveWindowTo({ x: 1000, y: 200 });
await this.floatWin.setWindowTouchable(true);
await this.floatWin.setUIContent('pages/KnowledgeCapsulePage');
await this.floatWin.showWindow();
// 监听意图变化,自动更新胶囊内容
emitter.on('intentChange', (event) => {
this.currentIntent = event.data?.intent || '';
this.updateCapsuleIcon();
});
}
/**
* 展开为知识卡片
* 显示当前编码意图相关的核心知识点
*/
async expandToCard(knowledge: KnowledgeNode): Promise<void> {
if (!this.floatWin) return;
this.currentLevel = 'card';
// 平滑动画过渡
await this.floatWin.resize({ width: 360, height: 480 });
await this.floatWin.moveWindowTo({ x: 720, y: 150 });
await this.floatWin.setUIContent('pages/KnowledgeCardPage');
// 传递知识数据
emitter.emit('showKnowledgeCard', { data: knowledge });
}
/**
* 展开为完整知识面板
* 包含知识图谱可视化、学习路径、代码示例
*/
async expandToPanel(topic: string): Promise<void> {
if (!this.floatWin) return;
this.currentLevel = 'panel';
await this.floatWin.resize({ width: 520, height: 800 });
await this.floatWin.moveWindowTo({ x: 560, y: 50 });
await this.floatWin.setUIContent('pages/KnowledgePanelPage');
emitter.emit('showKnowledgePanel', { data: { topic } });
}
/**
* 收起为胶囊
*/
async collapseToCapsule(): Promise<void> {
if (!this.floatWin) return;
this.currentLevel = 'capsule';
await this.floatWin.resize({ width: 80, height: 80 });
await this.floatWin.moveWindowTo({ x: 1000, y: 200 });
await this.floatWin.setUIContent('pages/KnowledgeCapsulePage');
}
private updateCapsuleIcon(): void {
// 根据当前意图更新胶囊图标
emitter.emit('updateCapsule', { data: { intent: this.currentIntent } });
}
destroy(): void {
this.floatWin?.destroyWindow();
}
}
4.4 智能体教学引擎(TutorAgentEngine)
这是系统的"大脑",负责理解开发者问题、检索知识、生成教学回复。
// agent/TutorAgentEngine.ets
import { ai } from '@kit.AiKit';
export interface TutorResponse {
answer: string;
codeSnippet?: string;
relatedConcepts: string[];
difficulty: string;
suggestedPractice?: string;
visualAid?: string; // 可生成的图表/流程图描述
}
export class TutorAgentEngine {
private agent: ai.AgentSession | null = null;
private knowledgeBase: Map<string, KnowledgeNode> = new Map();
/**
* 初始化教学智能体
* 加载鸿蒙开发知识库,配置教学风格
*/
async init(): Promise<void> {
// 加载本地知识库(约500个鸿蒙开发知识点)
await this.loadKnowledgeBase();
const model = await ai.createModel({
modelId: 'harmonyos-tutor-v1',
type: ai.ModelType.LOCAL,
capabilities: ['code_analysis', 'knowledge_qa', 'teaching']
});
this.agent = await ai.createAgentSession({
model: model,
systemPrompt: `你是一位经验丰富的HarmonyOS开发导师,擅长:
1. 用通俗易懂的语言解释复杂概念
2. 提供符合鸿蒙最佳实践的代码示例
3. 识别学习者的知识盲点并针对性讲解
4. 将抽象概念与具体场景结合
教学风格:耐心、循序渐进、注重实践。回答时请包含代码示例和注意事项。`
});
console.info('[Tutor] 教学智能体初始化完成');
}
/**
* 问答模式:回答开发者的具体问题
*/
async answerQuestion(question: string, context?: CodeContext): Promise<TutorResponse> {
if (!this.agent) throw new Error('智能体未初始化');
const enrichedPrompt = this.enrichWithContext(question, context);
const result = await this.agent.invoke({
input: { question: enrichedPrompt },
options: { maxTokens: 1024, temperature: 0.3 }
});
return this.parseTutorResponse(result);
}
/**
* 主动教学模式:根据编码意图推送知识
* 亮点:不是被动等待提问,而是主动"雪中送炭"
*/
async proactiveTeach(intent: CodingIntent, complexity: number): Promise<TutorResponse | null> {
// 只有当复杂度超过阈值或意图明确时才主动教学
if (complexity < 40 && intent === CodingIntent.UNKNOWN) return null;
const knowledge = this.knowledgeBase.get(intent);
if (!knowledge) return null;
// 检查用户是否已经掌握(通过历史记录)
if (knowledge.isMastered) return null;
const prompt = `用户正在处理"${intent}"相关代码,当前复杂度${complexity}。
请生成一段简短的知识点讲解(不超过200字),重点突出:
1. 最容易踩坑的地方
2. 一个实用的代码技巧
3. 官方文档中容易被忽略的细节`;
const result = await this.agent.invoke({
input: { question: prompt, context: knowledge },
options: { maxTokens: 512, temperature: 0.4 }
});
return this.parseTutorResponse(result);
}
/**
* 错误诊断模式:分析编译错误并提供修复方案
*/
async diagnoseError(errorMessage: string, codeSnippet: string): Promise<TutorResponse> {
const prompt = `HarmonyOS编译错误诊断:
错误信息:${errorMessage}
相关代码:${codeSnippet}
请:
1. 解释错误原因(用一句话)
2. 提供修复后的代码
3. 说明如何避免类似错误
4. 如果是鸿蒙特有的问题,强调与标准TS/JS的区别`;
const result = await this.agent.invoke({
input: { question: prompt },
options: { maxTokens: 1024, temperature: 0.2 }
});
return this.parseTutorResponse(result);
}
/**
* 学习路径生成:基于当前水平推荐下一步
*/
async generateLearningPath(currentSkills: string[]): Promise<{
nextTopic: string;
reason: string;
estimatedTime: string;
resources: string[];
}> {
const prompt = `基于用户已掌握的技能:${currentSkills.join(', ')},
推荐HarmonyOS开发的下一个学习主题。考虑:
1. 技能依赖关系(前置知识是否足够)
2. 实用性(工作中最常用)
3. 学习难度(循序渐进)
输出JSON格式:{nextTopic, reason, estimatedTime, resources[]}`;
const result = await this.agent.invoke({
input: { question: prompt },
options: { maxTokens: 512, temperature: 0.3 }
});
return JSON.parse(result.data?.path || '{}');
}
private enrichWithContext(question: string, context?: CodeContext): string {
if (!context) return question;
return `[上下文] 当前文件:${context.currentFile},编码意图:${context.detectedIntent},复杂度:${context.complexity}\n[问题] ${question}`;
}
private parseTutorResponse(result: ai.ModelOutput): TutorResponse {
const data = result.data || {};
return {
answer: data.answer || '',
codeSnippet: data.codeSnippet,
relatedConcepts: data.relatedConcepts || [],
difficulty: data.difficulty || 'intermediate',
suggestedPractice: data.suggestedPractice,
visualAid: data.visualAid
};
}
private async loadKnowledgeBase(): Promise<void> {
// 从本地JSON加载知识库
// 包含:ArkUI组件、状态管理、并发模型、网络请求、生命周期等
const knowledgeData = await import('../resources/knowledge_base.json');
knowledgeData.default.forEach((node: KnowledgeNode) => {
this.knowledgeBase.set(node.id, node);
});
}
}
4.5 胶囊页面(KnowledgeCapsulePage)
// pages/KnowledgeCapsulePage.ets
import { emitter } from '@kit.BasicServicesKit';
@Entry
@Component
struct KnowledgeCapsulePage {
@State currentIcon: string = '📘'; // 默认图标
@State isGlowing: boolean = false;
@State unreadTips: number = 0;
// 意图到图标的映射
private iconMap: Record<string, string> = {
'layout_design': '📐',
'state_management': '🔄',
'animation': '✨',
'networking': '🌐',
'navigation': '🧭',
'lifecycle': '♻️'
};
aboutToAppear() {
// 监听意图变化
emitter.on('updateCapsule', (event) => {
const intent = event.data?.intent || '';
this.currentIcon = this.iconMap[intent] || '📘';
});
// 监听新提示
emitter.on('newTip', () => {
this.unreadTips++;
this.isGlowing = true;
setTimeout(() => this.isGlowing = false, 3000);
});
}
build() {
Stack() {
// 外圈光晕(有新提示时)
if (this.isGlowing) {
Circle()
.width(90)
.height(90)
.fill('rgba(0, 176, 255, 0.2)')
.animation({
duration: 1000,
iterations: -1,
curve: Curve.EaseInOut,
playMode: PlayMode.Alternate
})
}
// 主胶囊
Column() {
Text(this.currentIcon)
.fontSize(32)
if (this.unreadTips > 0) {
Text(`${this.unreadTips}`)
.fontSize(10)
.fontColor('#FFF')
.backgroundColor('#FF1744')
.width(18)
.height(18)
.borderRadius(9)
.textAlign(TextAlign.Center)
.position({ x: 50, y: 0 })
}
}
.width(80)
.height(80)
.justifyContent(FlexAlign.Center)
.backgroundColor('rgba(255, 255, 255, 0.95)')
.borderRadius(40)
.shadow({ radius: 15, color: 'rgba(0,0,0,0.15)' })
.gesture(
GestureGroup(GestureMode.Sequence,
// 单击:展开知识卡片
TapGesture({ count: 1 })
.onAction(() => {
emitter.emit('expandToCard');
}),
// 双击:展开完整面板
TapGesture({ count: 2 })
.onAction(() => {
emitter.emit('expandToPanel');
}),
// 长按:语音提问
LongPressGesture({ duration: 800 })
.onAction(() => {
emitter.emit('startVoiceQuery');
})
)
)
}
.width('100%')
.height('100%')
.align(Alignment.Center)
}
}
4.6 知识卡片页面(KnowledgeCardPage)
// pages/KnowledgeCardPage.ets
import { emitter } from '@kit.BasicServicesKit';
@Entry
@Component
struct KnowledgeCardPage {
@State knowledge: KnowledgeNode | null = null;
@State isExpanded: boolean = false;
aboutToAppear() {
emitter.on('showKnowledgeCard', (event) => {
this.knowledge = event.data as KnowledgeNode;
});
}
build() {
Column() {
// 顶部:知识点标题与难度
Row() {
Text(this.knowledge?.title || '知识点')
.fontSize(18)
.fontWeight(FontWeight.Bold)
.layoutWeight(1)
Text(this.knowledge?.difficulty === 'beginner' ? '入门' :
this.knowledge?.difficulty === 'intermediate' ? '进阶' : '高级')
.fontSize(12)
.fontColor('#FFF')
.backgroundColor(
this.knowledge?.difficulty === 'beginner' ? '#00C853' :
this.knowledge?.difficulty === 'intermediate' ? '#FF9100' : '#FF1744'
)
.padding({ left: 8, right: 8, top: 2, bottom: 2 })
.borderRadius(4)
}
.width('100%')
.padding(16)
// 内容区
Scroll() {
Column() {
// 一句话总结
Text(this.knowledge?.summary || '')
.fontSize(14)
.fontColor('#666')
.width('100%')
.margin({ bottom: 12 })
// 代码示例(可展开)
if (this.knowledge?.codeExample) {
Column() {
Row() {
Text('💡 代码示例')
.fontSize(14)
.fontWeight(FontWeight.Medium)
.layoutWeight(1)
Button(this.isExpanded ? '收起' : '展开')
.fontSize(12)
.backgroundColor('transparent')
.fontColor('#2979FF')
.onClick(() => this.isExpanded = !this.isExpanded)
}
.width('100%')
if (this.isExpanded) {
Text(this.knowledge.codeExample)
.fontSize(13)
.fontFamily('monospace')
.fontColor('#333')
.backgroundColor('#f5f5f5')
.padding(12)
.borderRadius(8)
.width('100%')
.margin({ top: 8 })
}
}
.width('100%')
.padding(12)
.backgroundColor('#f8f9fa')
.borderRadius(8)
.margin({ bottom: 12 })
}
// 相关知识点
Text('🔗 相关知识点')
.fontSize(14)
.fontWeight(FontWeight.Medium)
.width('100%')
.margin({ bottom: 8 })
Row() {
ForEach(this.knowledge?.relatedNodes || [], (node: string) => {
Text(node)
.fontSize(12)
.fontColor('#2979FF')
.backgroundColor('#E3F2FD')
.padding({ left: 10, right: 10, top: 4, bottom: 4 })
.borderRadius(12)
.margin({ right: 8, bottom: 8 })
})
}
.width('100%')
.flexWrap(FlexWrap.Wrap)
}
.padding(16)
}
.layoutWeight(1)
// 底部操作
Row() {
Button('👍 已掌握')
.fontSize(14)
.backgroundColor('#E8F5E9')
.fontColor('#2E7D32')
.layoutWeight(1)
.onClick(() => this.markAsMastered())
Button('📖 深入学习')
.fontSize(14)
.backgroundColor('#2979FF')
.margin({ left: 8 })
.layoutWeight(1)
.onClick(() => emitter.emit('expandToPanel', { data: { topic: this.knowledge?.id } }))
}
.width('100%')
.padding(16)
}
.width('100%')
.height('100%')
.backgroundColor('#FFF')
.borderRadius(16)
}
private markAsMastered() {
emitter.emit('markMastered', { data: { id: this.knowledge?.id } });
emitter.emit('collapseToCapsule');
}
}
4.7 主入口与系统集成(Index.ets)
// Index.ets
import { ContextAwareEngine, CodingIntent } from './engine/ContextAwareEngine';
import { LearningLightController, LearningState } from './lighting/LearningLightController';
import { KnowledgeFloatWindow } from './float/KnowledgeFloatWindow';
import { TutorAgentEngine } from './agent/TutorAgentEngine';
import { ClipboardWatcher } from './ClipboardWatcher';
import { emitter } from '@kit.BasicServicesKit';
@Entry
@Component
struct ProgrammingTutorApp {
private contextEngine: ContextAwareEngine = new ContextAwareEngine();
private lightController: LearningLightController = new LearningLightController();
private floatWindow: KnowledgeFloatWindow = new KnowledgeFloatWindow();
private tutorEngine: TutorAgentEngine = new TutorAgentEngine();
// 学习行为追踪
private typingHistory: number[] = [];
private errorHistory: string[] = [];
private lastTypeTime: number = Date.now();
aboutToAppear() {
this.initSystem();
}
aboutToDisappear() {
this.contextEngine.destroy();
this.lightController.reset();
this.floatWindow.destroy();
}
async initSystem() {
// 1. 初始化沉浸光感
await this.lightController.init();
// 2. 初始化悬浮窗
await this.floatWindow.create();
// 3. 初始化智能体引擎
await this.tutorEngine.init();
// 4. 初始化上下文感知
await this.contextEngine.init();
// 当编码意图变化时,触发主动教学
this.contextEngine.onIntentChange(async (context) => {
// 更新光感状态
await this.lightController.updateState({
intent: context.detectedIntent,
complexity: context.complexity,
errorCount: this.errorHistory.length,
typingSpeed: this.calculateTypingSpeed(),
pauseDuration: (Date.now() - this.lastTypeTime) / 1000,
deleteRate: this.calculateDeleteRate()
});
// 主动推送相关知识
const tip = await this.tutorEngine.proactiveTeach(
context.detectedIntent,
context.complexity
);
if (tip) {
emitter.emit('newTip');
// 短暂闪烁提醒有新知识
await this.lightController.showMasteryProgress(0);
}
});
// 5. 监听剪贴板(捕获编译错误)
const clipboardWatcher = new ClipboardWatcher(async (text) => {
// 检测是否为编译错误
if (text.includes('error') || text.includes('Error')) {
this.errorHistory.push(text);
await this.lightController.errorAlert('type_mismatch');
// 自动诊断
const diagnosis = await this.tutorEngine.diagnoseError(text, '');
emitter.emit('showDiagnosis', { data: diagnosis });
}
});
await clipboardWatcher.startWatching();
// 6. 设置事件监听
this.setupEventListeners();
}
private setupEventListeners() {
emitter.on('expandToCard', async () => {
const context = this.contextEngine.getLastContext();
const knowledge = await this.getKnowledgeByIntent(context?.detectedIntent);
await this.floatWindow.expandToCard(knowledge);
await this.lightController.updateState({
intent: context?.detectedIntent || '',
complexity: context?.complexity || 0,
errorCount: this.errorHistory.length,
typingSpeed: 0, pauseDuration: 0, deleteRate: 0
});
});
emitter.on('expandToPanel', async (event) => {
await this.floatWindow.expandToPanel(event.data?.topic || '');
});
emitter.on('collapseToCapsule', async () => {
await this.floatWindow.collapseToCapsule();
});
emitter.on('startVoiceQuery', () => {
this.startVoiceInteraction();
});
}
private calculateTypingSpeed(): number {
const now = Date.now();
const recent = this.typingHistory.filter(t => now - t < 60000);
return recent.length;
}
private calculateDeleteRate(): number {
// 简化计算
return 0.1;
}
private async getKnowledgeByIntent(intent?: string): Promise<KnowledgeNode> {
// 从知识库获取对应知识点
return {
id: intent || 'default',
title: this.getIntentTitle(intent),
category: intent || 'general',
difficulty: 'intermediate',
summary: '正在加载知识点...',
relatedNodes: [],
isMastered: false
};
}
private getIntentTitle(intent?: string): string {
const titles: Record<string, string> = {
'layout_design': 'ArkUI布局设计',
'state_management': '状态管理',
'animation': '动画与过渡',
'networking': '网络请求',
'navigation': '页面路由',
'lifecycle': '生命周期'
};
return titles[intent || ''] || '鸿蒙开发基础';
}
private async startVoiceInteraction() {
// 启动语音识别,进入对话模式
await this.lightController.updateState({
intent: '', complexity: 0, errorCount: 0,
typingSpeed: 0, pauseDuration: 0, deleteRate: 0
});
// 实际语音交互实现...
}
build() {
Column() {
Text('🎓 HarmonyOS编程学习伴侣')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 8 })
Text('智能体正在后台运行...')
.fontSize(14)
.fontColor('#666')
Text('打开DevEco Studio开始编码,AI导师将自动陪伴')
.fontSize(12)
.fontColor('#999')
.margin({ top: 4 })
.textAlign(TextAlign.Center)
// 学习统计
Column() {
Text('📊 今日学习统计')
.fontSize(16)
.fontWeight(FontWeight.Medium)
.margin({ bottom: 12 })
Row() {
Column() {
Text('12')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor('#2979FF')
Text('知识点')
.fontSize(12)
.fontColor('#999')
}
.layoutWeight(1)
Column() {
Text('3')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor('#00C853')
Text('已掌握')
.fontSize(12)
.fontColor('#999')
}
.layoutWeight(1)
Column() {
Text('45min')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor('#FF9100')
Text('专注时长')
.fontSize(12)
.fontColor('#999')
}
.layoutWeight(1)
}
.width('100%')
}
.width('90%')
.padding(20)
.backgroundColor('#f8f9fa')
.borderRadius(12)
.margin({ top: 32 })
// 当前状态指示
Row() {
Text('当前状态:')
.fontSize(14)
.fontColor('#666')
Text('🟢 专注编码中')
.fontSize(14)
.fontColor('#00C853')
.fontWeight(FontWeight.Medium)
}
.margin({ top: 20 })
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
五、配置文件
// module.json5
{
"module": {
"name": "ProgrammingTutor",
"type": "entry",
"description": "鸿蒙智能体编程学习伴侣",
"mainElement": "EntryAbility",
"deviceTypes": ["phone", "tablet", "2in1"],
"pages": "$profile:main_pages",
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "编程学习伴侣主入口",
"icon": "$media:layered_image",
"label": "AI编程导师",
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": ["entity.system.home"],
"actions": ["action.system.home"]
}
]
}
],
"requestPermissions": [
{
"name": "ohos.permission.SYSTEM_FLOAT_WINDOW",
"reason": "需要悬浮窗权限以提供常驻学习辅助"
},
{
"name": "ohos.permission.ACCESSIBILITY",
"reason": "需要无障碍权限以感知编码上下文"
},
{
"name": "ohos.permission.READ_PASTEBOARD",
"reason": "读取剪贴板以检测编译错误"
},
{
"name": "ohos.permission.INTERNET",
"reason": "连接云端智能体服务"
},
{
"name": "ohos.permission.ACCESS_AI_MODEL",
"reason": "使用端侧AI模型进行代码分析"
},
{
"name": "ohos.permission.MICROPHONE",
"reason": "支持语音提问交互"
}
]
}
}
六、效果展示与使用场景
6.1 典型学习场景
场景A:ArkUI布局入门
小李正在学习
Column和Row布局,在DevEco Studio中输入Column() {后,屏幕右下角的胶囊自动变为📐图标。他好奇地点击,展开的知识卡片展示了Column的justifyContent和alignItems属性的区别,以及一个常见的居中布局代码模板。底部边框泛起柔和的蓝色呼吸光,表示"专注学习"状态。
场景B:状态管理困惑
小王在
@State和@Prop之间反复修改代码,删除率很高,停顿时间超过10秒。系统检测到困惑状态,边框变为琥珀色波浪光效。悬浮胶囊闪烁提醒,展开后智能体主动解释:"@State用于组件内部状态,@Prop用于父子组件单向传递。你当前场景需要父子双向通信,建议使用@Link。"并附带了三种状态装饰器的对比表格。
场景C:突破时刻
小张终于理解了
TaskPool和Worker的区别,成功将耗时操作移入后台线程。编译通过后,设备四周边框闪烁5次翠绿光芒,悬浮窗弹出庆祝动画:“🎉 恭喜掌握鸿蒙并发编程!你已超越78%的学习者。”
6.2 光效语义设计
| 学习状态 | 光效表现 | 触发条件 |
|---|---|---|
| 专注编码 | 底部蓝色慢呼吸 | 稳定输入,低删除率 |
| 遇到困惑 | 全边框琥珀波浪 | 高删除率+长停顿 |
| 成功突破 | 全边框绿色闪烁 | 从困惑状态恢复且编译通过 |
| 知识推送 | 底部进度条填充 | 掌握新知识点 |
| 编译错误 | 左侧红色双闪 | 检测到错误信息 |
七、性能与隐私优化
7.1 性能策略
// 智能体调用策略
const agentStrategy = {
// 端侧模型处理:快速响应场景
local: ['intent_recognition', 'simple_qa', 'syntax_check'],
// 云端模型处理:深度分析场景
cloud: ['architecture_review', 'learning_path', 'complex_diagnosis'],
// 缓存策略:常见问题的回答缓存24小时
cache: {
enabled: true,
ttl: 86400000,
maxSize: 100 // 最多缓存100条
}
};
7.2 隐私保护
- 代码不上云:所有代码分析优先在端侧完成
- 脱敏传输:必须上云时,变量名替换为
var1、var2 - 本地知识库:500+知识点完全本地存储
- 用户控制:可随时关闭上下文感知,切换为纯手动模式
八、总结与展望
本文展示了如何基于HarmonyOS 6(API 23)的悬浮导航和沉浸光感能力,构建一个鸿蒙智能体驱动的沉浸式编程学习伴侣。与传统编程学习工具不同,它具备三个核心创新:
- 上下文感知:通过无障碍服务理解开发者正在做什么,主动而非被动
- 情绪光感:将学习状态转化为可视光效,创造"第六感"学习体验
- 端云协同智能体:端侧快速响应 + 云端深度教学,兼顾速度与质量
未来演进方向:
- 多设备协同:手机悬浮窗 + 平板知识面板 + AR眼镜光效提示
- 社区化学习:学习数据匿名汇总,生成"鸿蒙开发者能力地图"
- 实战项目引导:从知识点学习到完整项目实战的智能路径规划
- 考试认证对接:学习进度与HarmonyOS开发者认证考试关联
HarmonyOS 6的智能体框架和系统级交互创新,正在让"AI导师常驻身边"成为现实。对于正在学习鸿蒙开发的开发者而言,这不仅是一个工具,更是一位24小时在线、懂你困惑、陪你成长的编程伙伴。
转载自:https://blog.csdn.net/u014727709/article/details/161323293
欢迎 👍点赞✍评论⭐收藏,欢迎指正
更多推荐




所有评论(0)