在这里插入图片描述

每日一句正能量

世间的纷扰从不会停歇,但内心的回应却可以选择。
外界的噪音、他人的情绪、突发的事件,我们无法控制它们是否发生,但我们永远有权利决定“如何回应”。

一、前言:当AI导师常驻屏幕边缘

学习HarmonyOS开发的过程中,开发者常常面临这样的困境:看着官方文档写代码,却在@State@Prop的区别上反复踩坑;跟着教程实现动画,却不知道animateToanimation的适用场景;想查询某个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布局入门

小李正在学习ColumnRow布局,在DevEco Studio中输入Column() {后,屏幕右下角的胶囊自动变为📐图标。他好奇地点击,展开的知识卡片展示了ColumnjustifyContentalignItems属性的区别,以及一个常见的居中布局代码模板。底部边框泛起柔和的蓝色呼吸光,表示"专注学习"状态。

场景B:状态管理困惑

小王在@State@Prop之间反复修改代码,删除率很高,停顿时间超过10秒。系统检测到困惑状态,边框变为琥珀色波浪光效。悬浮胶囊闪烁提醒,展开后智能体主动解释:"@State用于组件内部状态,@Prop用于父子组件单向传递。你当前场景需要父子双向通信,建议使用@Link。"并附带了三种状态装饰器的对比表格。

场景C:突破时刻

小张终于理解了TaskPoolWorker的区别,成功将耗时操作移入后台线程。编译通过后,设备四周边框闪烁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 隐私保护

  • 代码不上云:所有代码分析优先在端侧完成
  • 脱敏传输:必须上云时,变量名替换为var1var2
  • 本地知识库:500+知识点完全本地存储
  • 用户控制:可随时关闭上下文感知,切换为纯手动模式

八、总结与展望

本文展示了如何基于HarmonyOS 6(API 23)的悬浮导航沉浸光感能力,构建一个鸿蒙智能体驱动的沉浸式编程学习伴侣。与传统编程学习工具不同,它具备三个核心创新:

  1. 上下文感知:通过无障碍服务理解开发者正在做什么,主动而非被动
  2. 情绪光感:将学习状态转化为可视光效,创造"第六感"学习体验
  3. 端云协同智能体:端侧快速响应 + 云端深度教学,兼顾速度与质量

未来演进方向:

  • 多设备协同:手机悬浮窗 + 平板知识面板 + AR眼镜光效提示
  • 社区化学习:学习数据匿名汇总,生成"鸿蒙开发者能力地图"
  • 实战项目引导:从知识点学习到完整项目实战的智能路径规划
  • 考试认证对接:学习进度与HarmonyOS开发者认证考试关联

HarmonyOS 6的智能体框架和系统级交互创新,正在让"AI导师常驻身边"成为现实。对于正在学习鸿蒙开发的开发者而言,这不仅是一个工具,更是一位24小时在线、懂你困惑、陪你成长的编程伙伴。


转载自:https://blog.csdn.net/u014727709/article/details/161323293
欢迎 👍点赞✍评论⭐收藏,欢迎指正

Logo

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

更多推荐