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

HarmonyOS 屏幕方向控制完全指南:setPreferredOrientation 竖屏横屏自动旋转详解

文章目录

    • 背景
      • 方法总览
      • 屏幕方向控制
        • setPreferredOrientation — 设置偏好方向
      • 窗口焦点与触摸控制
      • 手势返回控制
      • 规避区(AvoidArea)—— 全面屏适配的关键
      • 写在最后

背景

近期发现一款很有意思的HarmonyOS 三方库, 地址 @pura/harmony-utils(V1.4.0) , 作者是"桃花镇童长老", 我这里也是直接通过该作者公布的源码进行案例编写进行,写了到目前写了一部分demo ,感觉确实很有帮助,这里呢也是开始写一个系列的演示demo 供大家参考。如有帮助可以在OpenHarmony中进行下载安装进行使用哦

案例demo导航展示

↓↓↓↓↓↓接下来言归正传 ↓↓↓↓
HarmonyOS 开发中有两个场景经常让初学者头疼:

一是视频、游戏页面需要强制横屏;二是全面屏手机的刘海、导航条让内容被遮挡,需要做安全区域适配
这两块WindowUtil都提供了对应的 API,一起来看。

方法总览

屏幕方向控制

setPreferredOrientation — 设置偏好方向
// 竖屏Button('竖屏').layoutWeight(1).height(36).fontSize(12).fontColor('#fff').backgroundColor('#3498DB').borderRadius(6).onClick(()=>{WindowUtil.setPreferredOrientation(window.Orientation.PORTRAIT).then(()=>{this.addLog('setPreferredOrientation(PORTRAIT)');}).catch((e:Error)=>{this.addLog(`Error:${e.message}`);});})// 横屏Button('横屏').layoutWeight(1).height(36).fontSize(12).fontColor('#fff').backgroundColor('#2980B9').borderRadius(6).onClick(()=>{WindowUtil.setPreferredOrientation(window.Orientation.LANDSCAPE).then(()=>{this.addLog('setPreferredOrientation(LANDSCAPE)');}).catch((e:Error)=>{this.addLog(`Error:${e.message}`);});})// 跟随传感器自动旋转Button('传感器自转').layoutWeight(1).height(36).fontSize(12).fontColor('#fff').backgroundColor('#1A6BB5').borderRadius(6).onClick(()=>{WindowUtil.setPreferredOrientation(window.Orientation.AUTO_ROTATION).then(()=>{this.addLog('setPreferredOrientation(AUTO_ROTATION)');}).catch((e:Error)=>{this.addLog(`Error:${e.message}`);});})// 系统决定(不强制)this.Btn('setPreferredOrientation(UNSPECIFIED) 系统判定','#154360',()=>{WindowUtil.setPreferredOrientation(window.Orientation.UNSPECIFIED).then(()=>{this.addLog('setPreferredOrientation(UNSPECIFIED)');}).catch((e:Error)=>{this.addLog(`Error:${e.message}`);});})// 查询当前偏好方向this.Btn('getPreferredOrientation()','#0E2C4B',()=>{try{this.addLog(`getPreferredOrientation() →${WindowUtil.getPreferredOrientation()}`);}catch(e){this.addLog(`Error:${e}`);}})

常用枚举值说明:

枚举含义
PORTRAIT竖屏(正向)
LANDSCAPE横屏(正向)
AUTO_ROTATION跟随传感器自动旋转
UNSPECIFIED由系统决定,不强制

setPreferredOrientation是异步方法,设置后系统会在适当时机旋转屏幕。

常见使用场景:

  • 视频全屏时切横屏:LANDSCAPE
  • 退出全屏时恢复竖屏:PORTRAIT
  • 应用整体支持自动旋转:AUTO_ROTATION

窗口焦点与触摸控制

顺带提一下窗口的可焦和可触控制:

// 设置窗口可获焦this.Btn('setWindowFocusable(true)','#7F8C8D',()=>{WindowUtil.setWindowFocusable(true).then(()=>{this.addLog('setWindowFocusable(true)');}).catch((e:Error)=>{this.addLog(`Error:${e.message}`);});})this.Btn('setWindowFocusable(false)','#7F8C8D',()=>{WindowUtil.setWindowFocusable(false).then(()=>{this.addLog('setWindowFocusable(false)');}).catch((e:Error)=>{this.addLog(`Error:${e.message}`);});})// 设置窗口可触摸this.Btn('setWindowTouchable(true)','#616A6B',()=>{WindowUtil.setWindowTouchable(true).then(()=>{this.addLog('setWindowTouchable(true)');}).catch((e:Error)=>{this.addLog(`Error:${e.message}`);});})this.Btn('setWindowTouchable(false)','#616A6B',()=>{WindowUtil.setWindowTouchable(false).then(()=>{this.addLog('setWindowTouchable(false)');}).catch((e:Error)=>{this.addLog(`Error:${e.message}`);});})

setWindowTouchable(false)可以让窗口穿透点击事件,适合做透明悬浮窗叠加效果。

手势返回控制

API 13 新增了手势返回的开关控制:

// 允许手势返回this.Btn('setGestureBackEnabled(true) 允许手势返回','#884EA0',()=>{WindowUtil.setGestureBackEnabled(true).then(()=>{this.addLog('setGestureBackEnabled(true)');}).catch((e:Error)=>{this.addLog(`Error:${e.message}`);});})// 禁用手势返回(适合游戏、全屏视频)this.Btn('setGestureBackEnabled(false) 禁用手势返回','#76448A',()=>{WindowUtil.setGestureBackEnabled(false).then(()=>{this.addLog('setGestureBackEnabled(false)');}).catch((e:Error)=>{this.addLog(`Error:${e.message}`);});})// 查询当前手势返回状态this.Btn('isGestureBackEnabled()','#6C3483',()=>{try{this.addLog(`isGestureBackEnabled() →${WindowUtil.isGestureBackEnabled()}`);}catch(e){this.addLog(`Error:${e}`);}})// 对话框手势返回控制this.Btn('setDialogBackGestureEnabled(true)','#5B2C6F',()=>{WindowUtil.setDialogBackGestureEnabled(true).then(()=>{this.addLog('setDialogBackGestureEnabled(true)');}).catch((e:Error)=>{this.addLog(`Error:${e.message}`);});})

规避区(AvoidArea)—— 全面屏适配的关键

规避区就是需要留出空间不放内容的区域,比如刘海、导航条、软键盘弹出时的区域。

// 系统规避区(状态栏+导航栏)this.Btn('getWindowAvoidArea(SYSTEM)','#2C3E50',()=>{try{constarea=WindowUtil.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);this.addLog(`getWindowAvoidArea(SYSTEM) topRect.height=${area.topRect.height}bottomRect.height=${area.bottomRect.height}`);}catch(e){this.addLog(`Error:${e}`);}})// 刘海/挖孔规避区this.Btn('getWindowAvoidArea(CUTOUT) 刘海屏','#212F3C',()=>{try{constarea=WindowUtil.getWindowAvoidArea(window.AvoidAreaType.TYPE_CUTOUT);this.addLog(`getWindowAvoidArea(CUTOUT) topRect.height=${area.topRect.height}`);}catch(e){this.addLog(`Error:${e}`);}})// 导航指示条规避区this.Btn('getWindowAvoidArea(NAVIGATION_INDICATOR)','#1B2631',()=>{try{constarea=WindowUtil.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR);this.addLog(`getWindowAvoidArea(NAVIGATION_INDICATOR) bottomRect.height=${area.bottomRect.height}`);}catch(e){this.addLog(`Error:${e}`);}})// 软键盘规避区this.Btn('getWindowAvoidArea(KEYBOARD) 软键盘','#17202A',()=>{try{constarea=WindowUtil.getWindowAvoidArea(window.AvoidAreaType.TYPE_KEYBOARD);this.addLog(`getWindowAvoidArea(KEYBOARD) bottomRect.height=${area.bottomRect.height}`);}catch(e){this.addLog(`Error:${e}`);}})

返回的AvoidArea对象包含四个方向的矩形:

字段含义
topRect顶部规避区(状态栏/刘海高度)
bottomRect底部规避区(导航栏/手势条高度)
leftRect左侧规避区(横屏刘海)
rightRect右侧规避区

实际使用:

// 获取状态栏高度用于设置顶部内边距constarea=WindowUtil.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);conststatusBarHeight=area.topRect.height;// 单位:px,需要转 vpconstnavBarHeight=area.bottomRect.height;

注意返回的高度单位是物理像素(px),布局用的是虚拟像素(vp),需要通过vp2px转换。

写在最后

屏幕方向和规避区是 HarmonyOS 适配里最常遇到的两个点。

记住:

  • 强制横/竖屏用setPreferredOrientation
  • 全面屏安全区域适配用getWindowAvoidArea(TYPE_SYSTEM)获取状态栏/导航栏高度
  • 软键盘弹出时的内容遮挡用getWindowAvoidArea(TYPE_KEYBOARD)

这几个掌握了,大部分适配问题都能搞定。

http://www.zskr.cn/news/1447274.html

相关文章:

  • 鸣潮工具箱:让《鸣潮》游戏体验流畅如丝的专业优化方案
  • 同花顺股票买入测试要点
  • 暗黑3自动按键助手:5分钟掌握智能游戏辅助,效率提升300%
  • Linux命令:swapon
  • 安全审查启发式方法:从线性审计到模式消除的实战指南
  • 原神帧率解锁终极指南:5分钟突破60FPS限制实现高刷新率游戏体验
  • 2026四川趣味运动会优质服务商:资质与案例参考 - 深度智识库
  • DIY真电容麦克风:从OPA运放电路到双振膜指向性控制
  • 从图片到PCB:DIY心形LED灯全流程解析与避坑指南
  • R语言TwoSampleMR包实战:手把手教你从GWAS数据到因果推断(附完整代码与数据)
  • 基于Arduino与超声波传感器的智能投票计数系统设计与实现
  • ChatGPT网页版输入后没反应?一个被忽略的Chrome/Edge/Safari浏览器语言设置项
  • 超简单!el_PP-OCRv5_mobile_rec_safetensors预处理流程详解(附代码示例)
  • 基于Arduino的双控制器电子钢琴制作:从方波合成到系统设计
  • Boss Show Time:3步实现招聘信息时间精准显示的求职导航仪
  • 本地视频怎么去水印:全场景实操方法与优质工具汇总
  • 面试反问面试官 10 句高情商话术|加分不踩雷
  • 手机直连卫星!又一批卫星互联网技术试验卫星升空
  • DIY电子维修光学支架:低成本打造稳定显微镜与放大镜工作台
  • Ubuntu 18.04太老了?别急着升级系统,教你安装VS Code 1.85.2稳定版(附旧版本.deb包下载指引)
  • STM32H743 UART接收优化方案:DMA双缓冲+IDLE空闲中断自动帧识别
  • 量子噪声建模:挑战、框架与应用实践
  • 机器学习入门——用Python+Excel实现简单预测
  • 基础篇--概念原理-21-大模型的推理参数:重复惩罚(Repetition Penalty)是什么?怎么理解?——从原理到实战,一篇讲透
  • 开源教育平台Sky Claw:从机电一体化原理到机器人控制实践
  • 从电路设计到生活应用:创客工作坊的实践路径与硬件开发指南
  • Linux/macOS下用Shell脚本自动批量下载SRA测序数据并转FASTQ
  • 7.4V锂电池充电IC芯片,可实现PD快充2.4A的方案分享
  • 5分钟掌握跨文件Excel搜索:终极批量查询方案
  • Tinkercad制作SpaceX火箭发射动画:零门槛3D建模与可视化编程实践