HarmonyOS鸿蒙Next中SideBarContainer怎么接入适人握持(握持检测)

HarmonyOS鸿蒙Next中SideBarContainer怎么接入适人握持(握持检测) 握持手感知能识别未握持、左手以及右手握持。

需要实现:

  • 左手握持时侧边栏在左边
  • 右手握持时侧边栏在右边
  • 未握持时自动收起侧边栏
3 回复

真机演示:

cke_25970.jpegcke_27602.jpeg

实现过程:

握持检测可参考:怎么实现 Mate80 系列同款握持检测?

侧边栏左右切换(节选关键代码):

@Local holdingHandStatus: number = 0;

case motion.HoldingHandStatus.LEFT_HAND_HELD: {
  this.holdingHandStatus = 0;
  this.holdingHandText = '左手握持';
  break;
}
case motion.HoldingHandStatus.RIGHT_HAND_HELD: {
  this.holdingHandStatus = 1;
  this.holdingHandText = '右手握持';
  break;
}

SideBarContainer(SideBarContainerType.Embed) {}
.sideBarPosition(this.holdingHandStatus ? SideBarPosition.End : SideBarPosition.Start)

未握持时自动关闭侧边栏(节选关键代码):

@Local isShown: boolean = false;

case motion.HoldingHandStatus.NOT_HELD: {
  this.isShown = false;
  this.holdingHandText = '未握持';
  break;
}

SideBarContainer(SideBarContainerType.Embed) {}
.showSideBar($$this.isShown)

完整代码:

前提条件:需要配置 ohos.permission.DETECT_GESTURE 权限并申请。

import { motion } from '@kit.MultimodalAwarenessKit';

@Entry
@ComponentV2
struct SideBarWoChi {
  @Local holdingHandText: string = "未识别";
  @Local holdingHandStatus: number = 0;
  @Local isShown: boolean = false;
  private callback = (data: motion.HoldingHandStatus) => {
    switch (data) {
      case motion.HoldingHandStatus.NOT_HELD: {
        this.isShown = false;
        this.holdingHandText = '未握持';
        break;
      }
      case motion.HoldingHandStatus.LEFT_HAND_HELD: {
        this.holdingHandStatus = 0;
        this.holdingHandText = '左手握持';
        break;
      }
      case motion.HoldingHandStatus.RIGHT_HAND_HELD: {
        this.holdingHandStatus = 1;
        this.holdingHandText = '右手握持';
        break;
      }
      case motion.HoldingHandStatus.BOTH_HANDS_HELD: {
        this.holdingHandText = '双手握持';
        break;
      }
    }
  };

  aboutToAppear(): void {
    try {
      motion.on('holdingHandChanged', this.callback);
    } catch (e) {
      console.error('Failed on; err code = ' + e.code);
    }
  }

  aboutToDisappear(): void {
    try {
      motion.off('holdingHandChanged'); // 移除所有同类订阅
    } catch (e) {
      console.error('Failed off; err code = ' + e.code);
    }
  }

  build() {
    SideBarContainer(SideBarContainerType.Embed) {
      Column() {
        // 侧边栏
      }
      .width('100%')

      Column() {
        // 主页面
        Text("握持方式")
          .fontSize(32)
        Text(this.holdingHandText)
          .fontSize(22)
      }
      .width('100%')
      .backgroundColor(Color.Pink)
      .justifyContent(FlexAlign.Center)
    }
    .sideBarPosition(this.holdingHandStatus ? SideBarPosition.End : SideBarPosition.Start)
    .animation({ duration: 300 })
    .showSideBar($$this.isShown)
  }
}

更多关于HarmonyOS鸿蒙Next中SideBarContainer怎么接入适人握持(握持检测)的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


SideBarContainer通过setTouchEventListener监听触摸事件,结合getDisplay().getRealSize()获取屏幕尺寸,计算触摸区域判断握持方向。使用WindowManageravoidArea接口获取系统避让区域,动态调整侧边栏位置。在onTouchEvent回调中处理ACTION_DOWNACTION_MOVE事件,根据触摸点坐标与屏幕边缘距离触发侧边栏显示/隐藏。

在HarmonyOS Next中,可以通过@ohos.sensor模块的握持检测传感器(HoldingDetectionResponse)与SideBarContainer组件结合,实现根据握持状态动态调整侧边栏位置和显隐。核心步骤如下:

  1. 申请传感器权限:在module.json5中声明ohos.permission.MANAGE_SENSOR权限。

  2. 监听握持状态

    • 使用sensor.on(sensor.SensorId.HOLDING_DETECTION, callback)注册监听。
    • 在回调函数中获取HoldingDetectionResponse.value,其值为:
      • 0:未握持
      • 1:左手握持
      • 2:右手握持
  3. 控制SideBarContainer

    • 根据握持状态值,动态设置SideBarContainer的controlButton位置(SideBarPosition.StartSideBarPosition.End)以及显隐状态(showSideBar属性)。
    • 左手握持:侧边栏位置设为Start(左侧),并显示。
    • 右手握持:侧边栏位置设为End(右侧),并显示。
    • 未握持:调用showSideBar(false)收起侧边栏。

关键代码示例:

import { sensor } from '@ohos.sensor';
import { SideBarContainer, SideBarPosition } from '@ohos.arkUI.API9';

// 1. 定义状态变量
@State sidebarPosition: SideBarPosition = SideBarPosition.Start;
@State isSidebarVisible: boolean = false;

// 2. 注册握持检测监听
sensor.on(sensor.SensorId.HOLDING_DETECTION, (data: sensor.HoldingDetectionResponse) => {
  switch(data.value) {
    case 1: // 左手
      this.sidebarPosition = SideBarPosition.Start;
      this.isSidebarVisible = true;
      break;
    case 2: // 右手
      this.sidebarPosition = SideBarPosition.End;
      this.isSidebarVisible = true;
      break;
    default: // 未握持
      this.isSidebarVisible = false;
      break;
  }
});

// 3. 在UI中绑定状态
SideBarContainer({
  controlButton: { position: this.sidebarPosition },
  showSideBar: this.isSidebarVisible
}) {
  // ... 侧边栏和主内容区
}

注意事项:

  • 握持检测属于系统级传感器,需确保设备硬件支持。
  • 监听器应在页面生命周期(如aboutToAppear/aboutToDisappear)中及时注册和注销,避免资源泄漏。
  • 侧边栏位置切换时,可考虑添加平滑过渡动画提升体验。

此方案直接利用系统传感器事件驱动UI更新,实现握持状态与SideBarContainer的联动。

回到顶部