当前位置: 首页 > news >正文

鸿蒙原生实战:智感握姿 – 左右手自动适配新闻列表

基于鸿蒙原生手持感知能力,实现设备握持姿态实时识别,左手持机图片居左、右手持机图片居右,配合流畅布局动画,打造更贴合单手操作习惯的新闻阅读体验。

效果说明

请求手持握姿势检测权限,授权成功即可识别左右手姿态,新闻卡片会根据握持方式自动交换图文位置,切换过程平滑无卡顿。

核心技术

  1. 申请权限配置
    module.json5配置权限:ohos.permission.DETECT_GESTURE
  2. 动态权限申请
    手势权限为敏感权限,通过abilityAccessCtrl动态申请,保证功能可用。
  3. 握持状态识别
    使用motion模块监听holdingHandChanged事件,获取左手/右手握持状态。
  4. 响应式状态驱动
    通过@Local声明响应式变量,状态变更自动刷新UI布局。
  5. 容器动画
    在组件容器上配置非对称动画,布局顺序变化时自动执行平滑过渡。

实现思路

  1. 页面初始化时申请ohos.permission.DETECT_GESTURE权限。
  2. 权限通过后,注册握持姿态监听。
  3. 检测到左手/右手时,更新isRightMode状态。
  4. 状态变化触发新闻卡片非对称动画执行切换图文排列方向
  5. 离开页面生命周期函数中关闭监听这一点不要忘记哦。

真机实测中发现太灵敏,偶发手机脱离手放到桌子上也会执行一次,可能我手机带着手机壳,或者放的时候误触。

关键代码说明

// 状态变更自动切换布局,直接访问this.isRightMode,不通过传参@BuilderNewsCard(item:NewsItem){Row(){if(this.isRightMode){this.NewsTextColumn(item)this.NewsImage(item)}else{this.NewsImage(item)this.NewsTextColumn(item)}}}

运行要求

  1. 必须真机运行,模拟器不支持握持传感器。
  2. 开启「手势检测」权限。
  3. 鸿蒙版本:6.0+、API20+

完整示例

import{motion}from'@kit.MultimodalAwarenessKit';import{BusinessError}from'@kit.BasicServicesKit';import{promptAction}from'@kit.ArkUI';import{abilityAccessCtrl}from'@kit.AbilityKit';// 新闻数据模型classNewsItem{id:number;title:string;summary:string;imageColor:Color;constructor(id:number,title:string,summary:string,color:Color){this.id=id;this.title=title;this.summary=summary;this.imageColor=color;}}@Entry @ComponentV2 struct Index{@Local isRightMode:boolean=false;@Local newsList:NewsItem[]=[newNewsItem(1,"鸿蒙Next正式发布","纯血鸿蒙不再兼容安卓,开启移动操作系统新纪元。",Color.Blue),newNewsItem(2,"V哥聊技术","深度解析ArkTS语言特性,带你弯道超车。",Color.Red),newNewsItem(3,"2026行业展望","AI赛道爆发,普通程序员如何抓住最后的机会?",Color.Green),newNewsItem(4,"SpaceX星舰发射","马斯克火星殖民计划又近了一步,震撼全人类。",Color.Orange),newNewsItem(5,"周末去哪儿玩","发现城市周边的小众露营地,放松身心好去处。",Color.Pink),];// 握持状态变化回调privateholdingHandCallback=(data:motion.HoldingHandStatus)=>{switch(data){casemotion.HoldingHandStatus.LEFT_HAND_HELD:this.isRightMode=false;break;casemotion.HoldingHandStatus.RIGHT_HAND_HELD:this.isRightMode=true;break;default:break;}};asyncaboutToAppear():Promise<void>{constatManager=abilityAccessCtrl.createAtManager();constcontext=this.getUIContext().getHostContext();try{atManager.requestPermissionsFromUser(context,['ohos.permission.DETECT_GESTURE'],(err,data)=>{if(err){console.error(`申请失败:${err.message}`);}else{if(data.authResults[0]===abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED){console.info("用户已授权");motion.on('holdingHandChanged',this.holdingHandCallback);promptAction.showToast({message:"已开启智能握持适配"});console.info('握持状态监听已启动');}else{promptAction.showToast({message:"请开启手势检测权限"});console.error('权限被拒绝');}}});}catch(err){leterror=errasBusinessError;console.error(`权限申请失败:${error.code},${error.message}`);}}aboutToDisappear():void{try{motion.off('holdingHandChanged',this.holdingHandCallback);console.info('握持状态监听已关闭');}catch(err){console.error('关闭监听失败');}}// 构建单个新闻卡片(带动画)@BuilderNewsCard(item:NewsItem){Row({space:20}){if(this.isRightMode){// 右手模式:文字在左,图片在右this.NewsTextColumn(item)this.NewsImage(item)}else{// 左手模式:图片在左,文字在右this.NewsImage(item)this.NewsTextColumn(item)}}.width('100%').padding(12).margin({bottom:8}).backgroundColor(Color.White).borderRadius(12).shadow({radius:4,color:'rgba(0,0,0,0.1)',offsetY:2}).animation({duration:300,curve:Curve.EaseInOut})}@BuilderNewsTextColumn(item:NewsItem){Column(){Text(item.title).fontSize(16).fontColor(Color.Black).fontWeight(FontWeight.Medium).margin({bottom:8})Text(item.summary).fontSize(14).fontColor('#666666').maxLines(2).textOverflow({overflow:TextOverflow.Ellipsis})}.layoutWeight(1).alignItems(HorizontalAlign.Start).padding({right:12}).transition(TransitionEffect.asymmetric(TransitionEffect.OPACITY.combine(TransitionEffect.translate({x:30})).animation({duration:300,curve:Curve.EaseInOut}),TransitionEffect.OPACITY.combine(TransitionEffect.translate({x:-30})).animation({duration:300,curve:Curve.EaseInOut})))}@BuilderNewsImage(item:NewsItem){Row().width(80).height(80).backgroundColor(item.imageColor).borderRadius(8).justifyContent(FlexAlign.Center).transition(TransitionEffect.asymmetric(TransitionEffect.OPACITY.combine(TransitionEffect.translate({x:-30})).animation({duration:300,curve:Curve.EaseInOut}),TransitionEffect.OPACITY.combine(TransitionEffect.translate({x:30})).animation({duration:300,curve:Curve.EaseInOut})))}build(){Column(){// 顶部提示栏Row(){Text(this.isRightMode?"右手模式(图在右)":"左手模式(图在左)").fontSize(14).fontColor(Color.White).padding({left:12,right:12,top:6,bottom:6}).backgroundColor('rgba(0,0,0,0.6)').borderRadius(20)}.width('100%').padding(12).justifyContent(FlexAlign.Center)// 新闻列表List(){ForEach(this.newsList,(item:NewsItem)=>{ListItem(){this.NewsCard(item)}},(item:NewsItem)=>item.id.toString())}.width('100%').height('100%').padding({left:12,right:12})}.width('100%').height('100%').backgroundColor('#F5F5F5')}}

代码下载地址:DetectGestureDemo

总结

本案例很简单,通过申请手持检测权限获取能力,通过监听手持状态修改状态变量,通过非对称动画完成图文左右切换,我比较懒就不找图了用不同颜色替代,不用的时候记得关闭监听。

http://www.jsqmd.com/news/597444/

相关文章:

  • 2128基于51单片机的60秒倒计时系统设计
  • 标识牌设计部室哪家性价比高,卓道标识值得考虑吗? - mypinpai
  • 2134基于51单片机的8155扩展彩灯控制系统设计
  • 2026年不锈钢水箱生产厂家年度盘点,哪家性价比高 - 工业品网
  • 2026年总结华振供水,市场竞争力强的产品选购指南 - 工业设备
  • 来电显示公司名怎么设置?2026年专业号码认证服务商推荐 - 企业服务推荐
  • AI辅助开发新体验:让快马平台的AI为你设计和优化ccswitch设置模型代码
  • 5分钟免费解锁Cursor Pro全部功能:终极破解指南
  • MusePublic艺术创作引擎保姆级教程:从安装到生成高清艺术图
  • 解锁3大核心能力:写给复古游戏爱好者的FBNeo实战指南
  • 全国范围内可靠的二次供水设备厂家有哪些推荐 - 工业推荐榜
  • 2129基于51单片机的6264 ADC0808 DAC0832 8255扩展实验系统设计
  • 2135基于51单片机的8155扩展流水灯实验系统设计
  • 三月七小助手:5分钟搞定星穹铁道每日任务,终极自动化工具完全指南
  • AutoMdxBuilder: 零基础高效制作专业MDX词典的自动化解决方案
  • 保存青春印记:GetQzonehistory让QQ空间回忆永存
  • 突破限制:跨设备移动系统的终极虚拟化解决方案
  • 2026年山东地区喜登枝安全鞋排名,质量优势与厂家实力解析 - mypinpai
  • 新手福音:在快马平台通过实例轻松理解ccswitch设置模型
  • 效率提升秘籍:用快马生成智能脚本,自动清理开发环境垃圾文件
  • 突破网盘限速壁垒:ctfileGet高效链接解析工具全攻略
  • VutronMusic:你的跨平台智能音乐管家终极指南
  • 免费音频转换器fre:ac:跨平台音乐格式转换的终极解决方案
  • VMware15.5安装全攻略:从下载到激活,一步不落(附永久许可证)
  • NetSonar终极指南:5分钟掌握跨平台网络诊断工具
  • 2127基于51单片机的595彩灯控制系统设计
  • 提升团队协作效率:用快马生成一键式node.js环境检测与安装脚本
  • 如何突破音频收听限制?打造个人离线音频库的完整方案
  • 别再死记硬背SDP交换流程了!用Chrome DevTools的webrtc-internals实战调试RTCPeerConnection
  • TranslucentTB:重塑Windows任务栏视觉体验的轻量化方案