HarmonyOS鸿蒙Next中SideBarContainer怎么接入适人握持(握持检测)
HarmonyOS鸿蒙Next中SideBarContainer怎么接入适人握持(握持检测) 握持手感知能识别未握持、左手以及右手握持。
需要实现:
- 左手握持时侧边栏在左边
- 右手握持时侧边栏在右边
- 未握持时自动收起侧边栏
真机演示:


实现过程:
握持检测可参考:怎么实现 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()获取屏幕尺寸,计算触摸区域判断握持方向。使用WindowManager的avoidArea接口获取系统避让区域,动态调整侧边栏位置。在onTouchEvent回调中处理ACTION_DOWN和ACTION_MOVE事件,根据触摸点坐标与屏幕边缘距离触发侧边栏显示/隐藏。
在HarmonyOS Next中,可以通过@ohos.sensor模块的握持检测传感器(HoldingDetectionResponse)与SideBarContainer组件结合,实现根据握持状态动态调整侧边栏位置和显隐。核心步骤如下:
-
申请传感器权限:在
module.json5中声明ohos.permission.MANAGE_SENSOR权限。 -
监听握持状态:
- 使用
sensor.on(sensor.SensorId.HOLDING_DETECTION, callback)注册监听。 - 在回调函数中获取
HoldingDetectionResponse.value,其值为:0:未握持1:左手握持2:右手握持
- 使用
-
控制SideBarContainer:
- 根据握持状态值,动态设置SideBarContainer的
controlButton位置(SideBarPosition.Start或SideBarPosition.End)以及显隐状态(showSideBar属性)。 - 左手握持:侧边栏位置设为
Start(左侧),并显示。 - 右手握持:侧边栏位置设为
End(右侧),并显示。 - 未握持:调用
showSideBar(false)收起侧边栏。
- 根据握持状态值,动态设置SideBarContainer的
关键代码示例:
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的联动。

