鸿蒙APP开发-带你实现耳聪记APP的振动反馈功能

2 阅读3分钟

答对了手机会震?HarmonyOS振动反馈与交互体验

如果你对乐理学习感兴趣,可以去鸿蒙应用市场搜一下**「耳聪记」**,下载下来体验体验。答对题目时手机振动一下,答错时振动两下,用触觉强化学习反馈。体验完了再回来看这篇文章,你会更清楚振动反馈是怎么实现的。


写在前面

大家好,我是一名写了十多年Web前端的老兵。从jQuery时代一路走到React/Vue,Web端的触觉反馈一直比较弱,最多用CSS动画模拟一下。去年开始转战鸿蒙生态,用ArkTS开发App,发现HarmonyOS的振动API非常丰富。

比如:

  • 短振动:Web端没有原生支持;鸿蒙里用vibrator.startVibration({type: 'time', duration: 50})
  • 振动效果:Web端无法实现;鸿蒙里支持预定义效果如haptic_feedback_effect
  • 权限申请:Web端不需要;鸿蒙里需要在module.json5里声明权限。

别担心,接下来这篇文章,我会用"耳聪记"的答题反馈,带你看看HarmonyOS怎么实现振动反馈。


这篇文章聊什么

耳聪记的振动反馈功能,核心要解决:

  1. 振动调用:使用vibrator API触发振动
  2. 不同反馈:答对和答错使用不同振动模式
  3. 权限配置:声明振动权限
  4. 用户体验:振动与其他反馈(颜色、声音)配合

第一步:配置振动权限

// module.json5
{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.VIBRATE"
      }
    ]
  }
}

第二步:实现振动反馈

// Web前端同学看这里:Web端几乎没有振动API
// 鸿蒙里vibrator提供了丰富的振动控制能力

import { vibrator } from '@kit.SensorKit';

// 短振动(答对)
function vibrateSuccess(): void {
  try {
    vibrator.startVibration({
      type: 'time',
      duration: 50
    }, {
      usage: 'alarm'
    });
  } catch (err) {
    console.error(`振动失败: ${err}`);
  }
}

// 双振动(答错)
function vibrateError(): void {
  try {
    // 第一次振动
    vibrator.startVibration({
      type: 'time',
      duration: 30
    }, {
      usage: 'alarm'
    });

    // 延迟后第二次振动
    setTimeout(() => {
      vibrator.startVibration({
        type: 'time',
        duration: 30
      }, {
        usage: 'alarm'
      });
    }, 100);
  } catch (err) {
    console.error(`振动失败: ${err}`);
  }
}

// 停止振动
function stopVibration(): void {
  try {
    vibrator.stopVibration();
  } catch (err) {
    console.error(`停止振动失败: ${err}`);
  }
}

第三步:集成到训练页面

// Web前端同学看这里:React里我们在onClick回调里处理反馈
// 鸿蒙里在按钮点击事件中调用振动API

@Entry
@Component
struct TrainingWithFeedback {
  @State isCorrect: boolean = false
  @State isAnswered: boolean = false
  @State feedbackText: string = ''
  @State feedbackColor: string = '#374151'

  checkAnswer(answer: string, correctAnswer: string) {
    this.isAnswered = true;
    this.isCorrect = answer === correctAnswer;

    if (this.isCorrect) {
      // 答对:短振动 + 绿色反馈
      vibrateSuccess();
      this.feedbackText = '正确!';
      this.feedbackColor = '#22c55e';
    } else {
      // 答错:双振动 + 红色反馈
      vibrateError();
      this.feedbackText = `错误,正确答案是: ${correctAnswer}`;
      this.feedbackColor = '#ef4444';
    }
  }

  build() {
    Column() {
      // 反馈显示
      if (this.isAnswered) {
        Text(this.feedbackText)
          .fontSize(18)
          .fontWeight(FontWeight.Bold)
          .fontColor(this.feedbackColor)
          .margin({ bottom: 16 })
          .animation({
            duration: 300,
            curve: Curve.EaseOut
          })
      }

      // 选项按钮示例
      Button('大三和弦')
        .width('100%')
        .height(48)
        .backgroundColor(this.getButtonColor('大三和弦'))
        .borderRadius(12)
        .margin({ top: 8 })
        .onClick(() => {
          this.checkAnswer('大三和弦', '小三和弦');
        })

      Button('小三和弦')
        .width('100%')
        .height(48)
        .backgroundColor(this.getButtonColor('小三和弦'))
        .borderRadius(12)
        .margin({ top: 8 })
        .onClick(() => {
          this.checkAnswer('小三和弦', '小三和弦');
        })
    }
    .padding(16)
  }

  private getButtonColor(option: string): string {
    if (!this.isAnswered) return '#f3f4f6';
    if (option === '小三和弦') return '#22c55e'; // 正确答案
    if (this.isCorrect) return '#22c55e';
    return '#ef4444';
  }
}

第四步:常见问题

4.1 振动不生效

问题:调用振动API但手机没反应。

解决:检查是否声明了ohos.permission.VIBRATE权限,以及设备是否开启了振动。

4.2 振动过于频繁

问题:快速答题时振动太密集。

解决:添加防抖逻辑,限制振动频率。

let lastVibrateTime = 0;
const VIBRATE_COOLDOWN = 200; // 200毫秒冷却时间

function vibrateWithCooldown(): void {
  const now = Date.now();
  if (now - lastVibrateTime < VIBRATE_COOLDOWN) return;

  lastVibrateTime = now;
  vibrateSuccess();
}

总结

这篇文章围绕"耳聪记"的振动反馈功能,讲解了:

振动API

  • vibrator.startVibration()的使用
  • 不同时长和模式的振动
  • 权限配置

交互体验

  • 答对/答错的不同反馈
  • 振动与视觉反馈配合
  • 防抖处理

如果你对"耳聪记"感兴趣,欢迎去鸿蒙应用市场搜索下载体验。