文章目录
- 背景
- 方法总览
- WindowUtil 是什么?
- getWindowProperties() — 一口气拿到所有属性
- 快捷状态检查方法
- isWindowSupportWideGamut() — 异步检测宽色域
- getWindowType() 和 getWindowStatus()
- findWindow 和 getLastWindow
- 错误处理要养成习惯
- 写在最后
背景
近期发现一款很有意思的HarmonyOS 三方库, 地址 @pura/harmony-utils(V1.4.0) , 作者是"桃花镇童长老", 我这里也是直接通过该作者公布的源码进行案例编写进行,写了到目前写了一部分demo ,感觉确实很有帮助,这里呢也是开始写一个系列的演示demo 供大家参考。如有帮助可以在OpenHarmony中进行下载安装进行使用哦
案例demo导航展示
↓↓↓↓↓↓接下来言归正传 ↓↓↓↓
刚上手 HarmonyOS 开发的时候,想知道当前窗口是不是全屏、有没有开隐私模式、屏幕亮度是多少——翻了一圈官方文档,找到了window.Window对象,但调用路径又长又绕。
用了WindowUtil之后,一行代码搞定,真的省了不少事。
方法总览
WindowUtil 是什么?
WindowUtil是对 HarmonyOS 原生@kit.ArkUI中window模块的封装,把常用的窗口操作都变成了更简洁的静态方法。
不用每次都去拿 Window 实例,直接WindowUtil.xxx()调用就行。
getWindowProperties() — 一口气拿到所有属性
最基础的用法是调getWindowProperties(),它返回一个包含窗口所有属性的对象。
try{constprops=WindowUtil.getWindowProperties();this.addLog(`type=${props.type}isFullScreen=${props.isFullScreen}isPrivacyMode=${props.isPrivacyMode}`);this.addLog(`brightness=${props.brightness}focusable=${props.focusable}touchable=${props.touchable}`);}catch(e){this.addLog(`Error:${e}`);}运行后你会看到类似这样的日志输出:
type=1 isFullScreen=false isPrivacyMode=false brightness=-1 focusable=true touchable=true返回字段说明:
| 字段 | 含义 | 典型值 |
|---|---|---|
type | 窗口类型(应用主窗口为1) | 1 |
isFullScreen | 是否全屏 | false |
isPrivacyMode | 是否隐私模式(截屏遮挡) | false |
brightness | 屏幕亮度,-1表示跟随系统 | -1 |
focusable | 窗口是否可获焦 | true |
touchable | 窗口是否可触摸 | true |
这个方法适合需要一次性读取多个属性的场景,比如页面加载时做状态同步。
快捷状态检查方法
如果只想知道某一个状态,不需要调getWindowProperties()然后再取字段,WindowUtil提供了一系列快捷的isXxx()方法。
// 是否全屏this.Btn('isFullScreen()','#2980B9',()=>{try{this.addLog(`isFullScreen() →${WindowUtil.isFullScreen()}`);}catch(e){this.addLog(`Error:${e}`);}})// 是否隐私模式this.Btn('isPrivacyMode()','#2980B9',()=>{try{this.addLog(`isPrivacyMode() →${WindowUtil.isPrivacyMode()}`);}catch(e){this.addLog(`Error:${e}`);}})// 是否屏幕常亮this.Btn('isKeepScreenOn()','#1A6BB5',()=>{try{this.addLog(`isKeepScreenOn() →${WindowUtil.isKeepScreenOn()}`);}catch(e){this.addLog(`Error:${e}`);}})// 是否可获焦this.Btn('isFocusable()','#1A6BB5',()=>{try{this.addLog(`isFocusable() →${WindowUtil.isFocusable()}`);}catch(e){this.addLog(`Error:${e}`);}})// 是否可触摸this.Btn('isTouchable()','#154360',()=>{try{this.addLog(`isTouchable() →${WindowUtil.isTouchable()}`);}catch(e){this.addLog(`Error:${e}`);}})// 是否透明this.Btn('isTransparent()','#154360',()=>{try{this.addLog(`isTransparent() →${WindowUtil.isTransparent()}`);}catch(e){this.addLog(`Error:${e}`);}})// 是否已获焦(当前是否在最前面)this.Btn('isFocused()','#0E4C86',()=>{try{this.addLog(`isFocused() →${WindowUtil.isFocused()}`);}catch(e){this.addLog(`Error:${e}`);}})// 窗口是否正在显示this.Btn('isWindowShowing()','#0E4C86',()=>{try{this.addLog(`isWindowShowing() →${WindowUtil.isWindowShowing()}`);}catch(e){this.addLog(`Error:${e}`);}})这些方法都是同步返回的,直接拿结果就行,不需要await。
isWindowSupportWideGamut() — 异步检测宽色域
唯一有点特殊的是isWindowSupportWideGamut(),它是异步方法,需要用.then()获取结果:
this.Btn('isWindowSupportWideGamut() async','#083E6E',()=>{WindowUtil.isWindowSupportWideGamut().then(v=>{this.addLog(`isWindowSupportWideGamut() →${v}`);}).catch((e:Error)=>{this.addLog(`Error:${e.message}`);});})宽色域(Wide Color Gamut)支持 P3 色彩空间,高端屏幕才有。这个值对做图像处理、视频播放的同学比较有用。
getWindowType() 和 getWindowStatus()
除了isXxx(),还有两个枚举值查询方法:
// 窗口类型(数字枚举)this.Btn('getWindowType()','#27AE60',()=>{try{this.addLog(`getWindowType() →${WindowUtil.getWindowType()}`);}catch(e){this.addLog(`Error:${e}`);}})// 窗口当前状态(正常/最小化/最大化等)this.Btn('getWindowStatus()','#1E8449',()=>{try{this.addLog(`getWindowStatus() →${WindowUtil.getWindowStatus()}`);}catch(e){this.addLog(`Error:${e}`);}})getWindowType()返回的是window.WindowType枚举值,应用主窗口一般是1(TYPE_APP)。
getWindowStatus()返回的是window.WindowStatusType枚举值,比如FULL_SCREEN、FLOATING等,对需要响应窗口状态变化的应用(如分屏场景)很有用。
findWindow 和 getLastWindow
有时候你需要拿到窗口对象本身去做更底层的操作:
// 按名称查找窗口this.Btn('findWindow("EntryAbility") 查找窗口','#E74C3C',()=>{constw=WindowUtil.findWindow('EntryAbility');this.addLog(`findWindow("EntryAbility") →${w?'Window found':'undefined'}`);})// 获取当前最顶层的窗口(异步)this.Btn('getLastWindow() 获取顶层窗口','#C0392B',()=>{WindowUtil.getLastWindow().then(w=>{this.addLog(`getLastWindow() → Window ok=${!!w}`);}).catch((e:Error)=>{this.addLog(`Error:${e.message}`);});})findWindow通过 ability 名字查找,拿到的是window.Window | undefined。getLastWindow是异步的,返回当前上下文中最顶层的窗口实例。
错误处理要养成习惯
注意看上面所有同步方法都包在try/catch里了。这不是多此一举——如果 WindowUtil 没有初始化、或者窗口已经销毁,这些方法会直接抛出异常。
所以无论是用getWindowProperties()还是各种isXxx(),都建议套一层try/catch,避免崩溃。
写在最后
窗口属性查询是很多功能的基础,比如做截屏保护要先判断isPrivacyMode(),做沉浸式布局要先查isFullScreen(),做显示适配要看getWindowStatus()。
WindowUtil把这些都封装成了最简洁的调用形式,建议先把这几个方法的返回值打印出来看看,心里有个底,后面做复杂功能就不容易踩坑了。