当前位置: 首页 > 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.jsqmd.com/news/935923/

相关文章:

  • Step 3.5 Flash vs 闭源模型:成本降低18倍的企业级AI解决方案终极指南
  • AWK实战:从文本数据中快速统计分组数量
  • Codex 完整介绍:OpenAI AI 编程代理的三种入口与核心能力
  • 网盘下载速度慢?8大平台直链解析工具帮你轻松提速
  • Arduino创意DIY:打造嘻哈风格智能珠宝盒的完整指南
  • ​2026年石家庄保定唐山邯郸秦皇岛衡水邢台承德奢侈品回收(名表名包珠宝首饰)怎么选?赵掌柜二奢参考指南(185-3117-2838) - GrowthUME
  • 深度解析OptiScaler:多GPU超分辨率技术的跨平台融合革命
  • 睿港国际移民:圣基茨护照申请如何选择专业机构? - 博客万
  • 同花顺股票买入测试要点
  • 从传感器到舵机:基于Arduino与ESP32的远程机械手系统全链路实践
  • 暗黑3自动按键助手:5分钟掌握智能游戏辅助,效率提升300%
  • Arduino TFT扩展板设计:从电平转换到PCB布局的完整实战指南
  • 艾尔登法环帧率解锁终极指南:如何免费提升游戏性能到144Hz
  • 2026年宜昌汽车贴膜行业横向测评白皮书 - GrowthUME
  • 佳能G3800 G3810 G5080 G6080 TS3380 MG3580 MG3680 TS5080清零软件全能版, 清零软件,5B00,P07,1700,1702,1704,亲测好用
  • Linux命令:swapon
  • 基于Arduino与离线语音模块的智能小车DIY:从硬件搭建到代码实现
  • 暗黑破坏神3智能助手:5分钟解放双手,游戏效率提升200%
  • 从数据管道到智能协同:六家数据中台厂商的AI融合路径与数据治理深度对比 - 博客万
  • CSS Grid 高级布局实战:从仪表盘到杂志排版的复杂自适应网格系统
  • 免费开源乐谱识别神器Audiveris:5分钟将纸质乐谱转为数字格式的完整指南
  • 大麦网抢票自动化:Python脚本完整配置与实战指南
  • 安全审查启发式方法:从线性审计到模式消除的实战指南
  • 2026四川趣味运动会优质服务商:资质与案例参考 - 深度智识库
  • ARM汇编新手避坑指南:从MOV指令的8个常见错误用法说起
  • DIY真电容麦克风:从OPA运放电路到双振膜指向性控制
  • 从图片到PCB:DIY心形LED灯全流程解析与避坑指南
  • 项目管理中如何进行项目干系人管理?
  • R语言TwoSampleMR包实战:手把手教你从GWAS数据到因果推断(附完整代码与数据)
  • STM32嵌入式系统接入PS/2键盘:协议解析与状态机实现