HarmonyOS 屏幕信息获取入门:getDefaultDisplaySync 与 getAllDisplays 详解
文章目录
- 一、前言
- 二、工具函数方法一览
- 三、`display.Display` 对象的核心字段
- 四、方法逐一详解
- 4.1 `getDefaultDisplaySync()` — 同步获取默认显示屏
- 4.2 `getPrimaryDisplaySync()` — 同步获取主屏(API 14+)
- 4.3 `getAllDisplays()` — 异步获取所有显示屏
- 五、完整演示代码
- 5.1 数据加载
- 5.2 UI 渲染
- 六、实际应用场景
- 场景 1:获取屏幕宽高用于自适应布局
- 场景 2:获取 DPI 计算英寸大小
- 场景 3:多屏设备遍历所有屏幕
- 七、注意事项
- 八、小结
一、前言
近期发现一款很有意思的HarmonyOS 三方库, 地址 @pura/harmony-utils(V1.4.0) , 作者是"桃花镇童长老", 我这里也是直接通过该作者公布的源码进行案例编写进行,写了到目前写了一部分demo ,感觉确实很有帮助,这里呢也是开始写一个系列的演示demo 供大家参考。如有帮助可以在OpenHarmony中进行下载安装进行使用哦
案例demo导航展示
↓↓↓↓↓↓接下来言归正传 ↓↓↓↓
在 HarmonyOS 应用开发中,获取屏幕信息是一项基础需求——无论是适配不同屏幕尺寸、判断多屏环境,还是读取刷新率以优化动画性能,都需要先拿到display.Display对象。
DisplayUtil对 HarmonyOSdisplay模块进行了封装,本文聚焦于获取屏幕基本信息的三个方法,结合DisplayUtilDemoPage.ets的完整演示代码进行讲解。
二、工具函数方法一览
// 同步获取默认 Display 对象staticgetDefaultDisplaySync():display.Display// 同步获取主屏 Display 对象(API 14+,2in1 设备感知外接屏)staticgetPrimaryDisplaySync():display.Display// 异步获取所有 Display 对象列表(支持多屏场景)staticasyncgetAllDisplays():Promise<Array<display.Display>>三、display.Display对象的核心字段
调用上述方法后,会返回display.Display对象,常用字段如下:
| 字段 | 类型 | 说明 |
|---|---|---|
id | number | 显示屏唯一 ID |
name | string | 显示屏名称 |
width | number | 屏幕宽度(px) |
height | number | 屏幕高度(px) |
densityDPI | number | 屏幕 DPI(每英寸点数) |
densityPixels | number | 屏幕逻辑密度(如 3.0 表示 xxxhdpi) |
refreshRate | number | 刷新率(Hz,如 60、90、120) |
orientation | display.Orientation | 当前方向 |
state | display.DisplayState | 显示状态 |
四、方法逐一详解
4.1getDefaultDisplaySync()— 同步获取默认显示屏
源码:
staticgetDefaultDisplaySync():display.Display{returndisplay.getDefaultDisplaySync();}说明:
同步方法,立即返回默认显示屏对象,不需要await。适合在初始化阶段快速获取屏幕参数。
注意:若屏幕不可用会抛出
BusinessError 1400001,建议用try-catch包裹。
4.2getPrimaryDisplaySync()— 同步获取主屏(API 14+)
源码:
staticgetPrimaryDisplaySync():display.Display{if(deviceInfo.sdkApiVersion>=14){returndisplay.getPrimaryDisplaySync();}else{returndisplay.getDefaultDisplaySync();}}说明:
- API 14 以下:自动降级为
getDefaultDisplaySync()。 - API 14+:对于2in1 设备(类似 PC/Mac 的双屏形态):
- 外接屏幕时:返回当前主屏幕的 Display 对象(可能是外接屏)。
- 未外接屏幕时:返回设备自带屏幕的 Display 对象。
- 普通手机/平板:与
getDefaultDisplaySync()效果相同。
4.3getAllDisplays()— 异步获取所有显示屏
源码:
staticasyncgetAllDisplays():Promise<Array<display.Display>>{returndisplay.getAllDisplays();}说明:
异步方法,返回当前系统中所有显示屏的数组。在多屏场景(如 2in1 外接显示器、投屏)中,可以遍历所有屏幕,获取每块屏的尺寸、刷新率等参数。
五、完整演示代码
DisplayUtilDemoPage.ets中屏幕信息部分的完整代码:
5.1 数据加载
loadBasicDisplay(){try{// getDefaultDisplaySync()constdefaultDisplay=DisplayUtil.getDefaultDisplaySync();this.defaultDisplayInfo=`id:${defaultDisplay.id}, name:${defaultDisplay.name}, width:${defaultDisplay.width}px, height:${defaultDisplay.height}px, density:${defaultDisplay.densityDPI}, refreshRate:${defaultDisplay.refreshRate}Hz`;this.addLog('Display',`getDefaultDisplaySync() OK - id:${defaultDisplay.id}`,'success');}catch(e){this.defaultDisplayInfo=`获取失败:${(easError).message}`;this.addLog('Display',`getDefaultDisplaySync() 失败:${(easError).message}`,'error');}try{// getPrimaryDisplaySync()constprimaryDisplay=DisplayUtil.getPrimaryDisplaySync();this.primaryDisplayInfo=`id:${primaryDisplay.id}, name:${primaryDisplay.name}, width:${primaryDisplay.width}px, height:${primaryDisplay.height}px`;this.addLog('Display',`getPrimaryDisplaySync() OK - id:${primaryDisplay.id}`,'success');}catch(e){this.primaryDisplayInfo=`获取失败:${(easError).message}`;this.addLog('Display',`getPrimaryDisplaySync() 失败:${(easError).message}`,'error');}// getAllDisplays() - 异步this.allDisplaysLoading=true;DisplayUtil.getAllDisplays().then((displays)=>{this.allDisplaysLoading=false;this.allDisplaysInfo=`共${displays.length}个显示屏\n`+displays.map((d,i)=>`[${i}] id=${d.id},${d.width}x${d.height}, rate=${d.refreshRate}Hz`).join('\n');this.addLog('Display',`getAllDisplays() OK -${displays.length}个屏幕`,'success');}).catch((e:Error)=>{this.allDisplaysLoading=false;this.allDisplaysInfo=`获取失败:${e.message}`;this.addLog('Display',`getAllDisplays() 失败:${e.message}`,'error');});}5.2 UI 渲染
// ══ 屏幕信息 ════════════════════════════════════════if(this.activeTab===0){// getDefaultDisplaySync()this.buildSectionCard('getDefaultDisplaySync() - 获取默认显示屏',[{label:'方法',value:'DisplayUtil.getDefaultDisplaySync()'},{label:'返回值',value:this.defaultDisplayInfo},]asSectionRow[])// getPrimaryDisplaySync()this.buildSectionCard('getPrimaryDisplaySync() - 获取主屏信息 (API14+)',[{label:'方法',value:'DisplayUtil.getPrimaryDisplaySync()'},{label:'返回值',value:this.primaryDisplayInfo},]asSectionRow[])// getAllDisplays()Column(){Row(){Text('getAllDisplays() - 获取所有显示屏').fontSize(13).fontColor('#666').fontWeight(FontWeight.Medium)if(this.allDisplaysLoading){LoadingProgress().width(16).height(16).margin({left:6})}}.width('100%').margin({bottom:8}).alignSelf(ItemAlign.Start)Text(this.allDisplaysInfo||'加载中...').fontSize(11).fontFamily('monospace').fontColor('#555').width('100%').textAlign(TextAlign.Start)}.width('100%').padding(14).backgroundColor('#FFFFFF').borderRadius(12)// API 说明this.buildApiCard('Display API 列表',[{name:'getDefaultDisplaySync()',desc:'同步获取默认 display 对象,含宽/高/密度/刷新率'},{name:'getPrimaryDisplaySync()',desc:'同步获取主屏(API14+),2in1 外接屏时返回当前主屏'},{name:'getAllDisplays()',desc:'异步获取所有 display 对象列表(支持多屏)'},]asApiRow[])}六、实际应用场景
场景 1:获取屏幕宽高用于自适应布局
constdisplay=DisplayUtil.getDefaultDisplaySync();constscreenWidth=display.width;// 单位 pxconstscreenHeight=display.height;// 计算布局比例constratio=screenWidth/screenHeight;场景 2:获取 DPI 计算英寸大小
constd=DisplayUtil.getDefaultDisplaySync();constwInch=d.width/d.densityDPI;consthInch=d.height/d.densityDPI;constdiagonal=Math.sqrt(wInch*wInch+hInch*hInch);console.info(`屏幕对角线约${diagonal.toFixed(1)}英寸`);Demo 中完整实现了这个计算:
loadScreenSize(){this.screenWidth=`${DisplayUtil.getWidth()}px`;this.screenHeight=`${DisplayUtil.getHeight()}px`;try{constd=DisplayUtil.getDefaultDisplaySync();constwInch=d.width/d.densityDPI;consthInch=d.height/d.densityDPI;constdiag=Math.sqrt(wInch*wInch+hInch*hInch);this.screenSize=`${diag.toFixed(2)}英寸 (${wInch.toFixed(2)}x${hInch.toFixed(2)})`;}catch(e){this.screenSize='计算失败';}}场景 3:多屏设备遍历所有屏幕
DisplayUtil.getAllDisplays().then((displays)=>{displays.forEach((d,index)=>{console.info(`[${index}]${d.width}x${d.height}@${d.refreshRate}Hz`);});});七、注意事项
同步 vs 异步:
getDefaultDisplaySync和getPrimaryDisplaySync是同步方法,不需要await;getAllDisplays是异步方法,需要.then()或await。异常处理:三个方法都可能抛出
BusinessError 1400001(无效显示屏),建议加try-catch。API 版本兼容:
getPrimaryDisplaySync在 API 14 以下会降级,代码中已处理,无需担心兼容性。单位统一:所有尺寸单位为px(物理像素),与 ArkUI 中的 vp(虚拟像素)不同,换算公式:
vp = px / densityPixels。
八、小结
| 方法 | 同步/异步 | 适用场景 |
|---|---|---|
getDefaultDisplaySync() | 同步 | 快速获取默认屏幕信息 |
getPrimaryDisplaySync() | 同步 | API14+,2in1 主屏感知 |
getAllDisplays() | 异步 | 多屏枚举与管理 |
三个方法覆盖了绝大多数屏幕信息获取场景,是开发屏幕自适应布局的基础工具。
