文章目录背景方法总览屏幕方向控制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{constareaWindowUtil.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{constareaWindowUtil.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{constareaWindowUtil.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{constareaWindowUtil.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右侧规避区实际使用// 获取状态栏高度用于设置顶部内边距constareaWindowUtil.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);conststatusBarHeightarea.topRect.height;// 单位px需要转 vpconstnavBarHeightarea.bottomRect.height;注意返回的高度单位是物理像素px布局用的是虚拟像素vp需要通过vp2px转换。写在最后屏幕方向和规避区是 HarmonyOS 适配里最常遇到的两个点。记住强制横/竖屏用setPreferredOrientation全面屏安全区域适配用getWindowAvoidArea(TYPE_SYSTEM)获取状态栏/导航栏高度软键盘弹出时的内容遮挡用getWindowAvoidArea(TYPE_KEYBOARD)这几个掌握了大部分适配问题都能搞定。
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{constareaWindowUtil.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{constareaWindowUtil.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{constareaWindowUtil.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{constareaWindowUtil.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右侧规避区实际使用// 获取状态栏高度用于设置顶部内边距constareaWindowUtil.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);conststatusBarHeightarea.topRect.height;// 单位px需要转 vpconstnavBarHeightarea.bottomRect.height;注意返回的高度单位是物理像素px布局用的是虚拟像素vp需要通过vp2px转换。写在最后屏幕方向和规避区是 HarmonyOS 适配里最常遇到的两个点。记住强制横/竖屏用setPreferredOrientation全面屏安全区域适配用getWindowAvoidArea(TYPE_SYSTEM)获取状态栏/导航栏高度软键盘弹出时的内容遮挡用getWindowAvoidArea(TYPE_KEYBOARD)这几个掌握了大部分适配问题都能搞定。