HarmonyOS震动反馈开发——提升用户体验的触觉交互

HarmonyOS震动反馈开发——提升用户体验的触觉交互

技术栈:HarmonyOS 5.0 + ArkTS + @ohos.vibrator

适用场景:按钮反馈、操作确认、游戏交互、手机排水


前言

触觉反馈是提升用户体验的重要手段。本文将介绍如何在HarmonyOS应用中使用震动API实现各种触觉交互效果。

一、震动API概述

HarmonyOS提供了@ohos.vibrator模块用于控制设备震动:

  • 时长震动:指定震动持续时间
  • 预设效果:使用系统预设的震动模式
  • 自定义模式:通过震动模式数组实现复杂效果

二、权限配置

// module.json5
{
  "requestPermissions": [
    {
      "name": "ohos.permission.VIBRATE",
      "reason": "$string:vibrate_reason",
      "usedScene": {
        "abilities": ["EntryAbility"],
        "when": "inuse"
      }
    }
  ]
}

三、基础使用

3.1 简单震动

import vibrator from '@ohos.vibrator';

// 震动100毫秒
async function simpleVibrate(): Promise<void> {
  try {
    await vibrator.startVibration({
      type: 'time',
      duration: 100
    }, {
      id: 0,
      usage: 'unknown'
    });
  } catch (err) {
    console.error('震动失败:', err);
  }
}

3.2 停止震动

async function stopVibrate(): Promise<void> {
  try {
    await vibrator.stopVibration(vibrator.VibratorStopMode.VIBRATOR_STOP_MODE_TIME);
  } catch (err) {
    console.error('停止震动失败:', err);
  }
}

3.3 回调方式

vibrator.startVibration({
  type: 'time',
  duration: 50
}, {
  id: 0,
  usage: 'notification'
}, (error) => {
  if (error) {
    console.error('震动失败:', error);
  }
});

四、实际应用场景

4.1 按钮点击反馈

@Component
struct VibrationButton {
  @Prop text: string = '按钮';
  onClick: () => void = () => {};

  private async vibrateFeedback(): Promise<void> {
    try {
      await vibrator.startVibration({
        type: 'time',
        duration: 30  // 短促震动
      }, { id: 0, usage: 'touch' });
    } catch (err) {}
  }

  build() {
    Button(this.text)
      .onClick(() => {
        this.vibrateFeedback();
        this.onClick();
      })
  }
}

4.2 操作成功/失败反馈

// 成功反馈 - 短促单次
async function successFeedback(): Promise<void> {
  await vibrator.startVibration({
    type: 'time',
    duration: 50
  }, { id: 0, usage: 'notification' });
}

// 失败反馈 - 连续两次
async function errorFeedback(): Promise<void> {
  await vibrator.startVibration({ type: 'time', duration: 100 }, { id: 0, usage: 'alarm' });
  await new Promise(resolve => setTimeout(resolve, 150));
  await vibrator.startVibration({ type: 'time', duration: 100 }, { id: 0, usage: 'alarm' });
}

4.3 手机排水场景

export class AudioEngine {
  private enableVibration: boolean = false;

  setVibrationEnabled(enabled: boolean): void {
    this.enableVibration = enabled;
  }

  async start(durationSeconds: number): Promise<void> {
    // 启动音频播放...
    
    // 配合震动增强排水效果
    if (this.enableVibration) {
      this.startVibration();
    }
  }

  private startVibration(): void {
    const config = getAppConfig();
    if (config.feature.vibrationPattern.length > 0) {
      try {
        vibrator.startVibration({
          type: 'time',
          duration: 100
        }, {
          id: 0,
          usage: 'unknown'
        });
      } catch (err) {
        console.error('启动震动失败:', err);
      }
    }
  }

  private stopVibration(): void {
    try {
      vibrator.stopVibration(vibrator.VibratorStopMode.VIBRATOR_STOP_MODE_TIME);
    } catch (err) {
      console.error('停止震动失败:', err);
    }
  }
}

4.4 测试记录确认

private recordThreshold(): void {
  // 记录测试结果...
  
  // 震动反馈确认
  try {
    vibrator.startVibration({
      type: 'time',
      duration: 50
    }, {
      id: 0,
      usage: 'notification'
    }, (error) => {
      if (error) {
        console.error('Vibration failed:', error);
      }
    });
  } catch (err) {
    console.error('Vibration exception:', err);
  }
}

五、震动配置管理

export interface FeatureConfig {
  enableVibration: boolean;
  vibrationPattern: number[];  // [震动时长, 间隔, 震动时长, ...]
}

// 手机排水配置
export const WaterEjectorConfig = {
  feature: {
    enableVibration: true,
    vibrationPattern: [100, 50, 100, 50],  // 震动100ms, 停50ms, 震动100ms, 停50ms
  }
};

// 听力测试配置
export const HearingTestConfig = {
  feature: {
    enableVibration: false,  // 听力测试不需要震动
    vibrationPattern: [],
  }
};

六、用户设置控制

@Entry
@Component
struct SettingsPage {
  @State vibrationEnabled: boolean = true;

  aboutToAppear(): void {
    this.loadSettings();
  }

  async loadSettings(): Promise<void> {
    this.vibrationEnabled = await PreferencesUtil.getBoolean('vibration_enabled', true);
  }

  async toggleVibration(): Promise<void> {
    this.vibrationEnabled = !this.vibrationEnabled;
    await PreferencesUtil.putBoolean('vibration_enabled', this.vibrationEnabled);
    
    // 更新音频引擎设置
    AudioEngine.getInstance().setVibrationEnabled(this.vibrationEnabled);
    
    // 反馈当前状态
    if (this.vibrationEnabled) {
      vibrator.startVibration({ type: 'time', duration: 50 }, { id: 0, usage: 'touch' });
    }
  }

  build() {
    Row() {
      Text('震动反馈')
      Toggle({ type: ToggleType.Switch, isOn: this.vibrationEnabled })
        .onChange(() => this.toggleVibration())
    }
  }
}

七、避坑指南

  1. 权限声明:必须在module.json5中声明VIBRATE权限
  2. 异常处理:震动API可能失败,需要try-catch
  3. 用户控制:提供开关让用户控制是否启用震动
  4. 适度使用:过度震动会影响用户体验和电池寿命
  5. 设备兼容:部分设备可能不支持震动

总结

本文介绍了HarmonyOS震动API的使用方法和实际应用场景。合理使用触觉反馈可以显著提升用户体验,但要注意适度使用并提供用户控制选项。

posted @ 2025-12-18 11:06  柠果丶  阅读(7)  评论(0)    收藏  举报