1# 使用Display实现屏幕属性查询及状态监听 (ArkTS)
2
3## 场景介绍
4
5[Display](../reference/apis-arkui/js-apis-display.md)屏幕属性提供管理设备屏幕的一些基础能力,例如获取默认显示设备的相关信息、获取全部显示设备的信息,此外还能对显示设备的插拔行为进行监听。应用可以根据对应的屏幕信息、屏幕状态变化、屏幕折叠状态等适配不同的UI界面显示。
6
7屏幕属性的常见使用场景有以下几种:
8
9- 查询屏幕信息:包括屏幕的分辨率、物理像素密度、逻辑像素密度、刷新率、屏幕尺寸、屏幕旋转方向、屏幕旋转角度等,具体可见[Display属性](../reference/apis-arkui/js-apis-display.md#属性)。
10- 监听屏幕状态变化,包括屏幕旋转变化,屏幕分辨率变化、屏幕刷新率变化等。
11- 查询当前设备是否为可折叠设备,同时支持折叠状态(展开/折叠)变化的监听。
12
13## 接口说明
14
15屏幕属性的常用接口如下表所示,更多功能及接口说明和使用请见[@ohos.display (屏幕属性)](../reference/apis-arkui/js-apis-display.md)。
16
17| 接口                                                         | 描述                                                         |
18| ------------------------------------------------------------ | ------------------------------------------------------------ |
19| getAllDisplays(): Promise<Array\<Display>>                   | 获取当前所有的Display对象,使用Promise异步回调。             |
20| getDefaultDisplaySync(): Display                             | 获取当前默认的display对象。                                  |
21| getDisplayByIdSync(displayId: number): Display               | 根据DisplayId获取对应的Display对象。                         |
22| on(type: 'add'\|'remove'\|'change', callback: Callback\<number>): void | 开启显示设备变化的监听。                                     |
23| off(type: 'add'\|'remove'\|'change', callback?: Callback\<number>): void | 关闭显示设备变化的监听。                                     |
24| on(type: 'captureStatusChange', callback: Callback\<boolean>): void | 开启屏幕截屏、投屏、录屏状态变化的监听。                     |
25| off(type: 'captureStatusChange', callback?: Callback\<boolean>): void | 关闭屏幕截屏、投屏、录屏状态变化的监听。                     |
26| on(type: 'availableAreaChange', callback: Callback\<Rect>): void | 开启当前设备屏幕的可用区域监听。当前设备屏幕有可用区域变化时,触发回调函数,返回可用区域。 |
27| off(type: 'availableAreaChange', callback?: Callback\<Rect>): void | 关闭当前设备屏幕可用区域变化的监听。                         |
28| isFoldable(): boolean                                        | 检查设备是否可折叠。                                         |
29| on(type: 'foldStatusChange', callback: Callback\<FoldStatus>): void | 开启折叠设备折叠状态变化的监听。                             |
30| off(type: 'foldStatusChange', callback?: Callback\<FoldStatus>): void | 关闭折叠设备折叠状态变化的监听。                             |
31
32## 获取Display对象
33
34Display对象,即屏幕实例,提供屏幕相关属性及监听变化的接口。目前有以下几种不同获取Display的方式,开发者可根据具体场景需要选择使用。
35
36- 获取当前默认的Display对象:使用getDefaultDisplaySync()接口获取。
37- 获取当前所有Display对象:使用getAllDisplays()获取。
38- 根据屏幕Id获取对应的Display对象:使用getDisplayByIdSync()接口获取。
39
40此处,以使用getDefaultDisplaySync()获取当前默认Display对象为例,示例如下:
41
42```ts
43import { display } from '@kit.ArkUI';
44
45let displayClass: display.Display | null = null;
46displayClass = display.getDefaultDisplaySync();
47// 确保获取到Display对象,即displayClass,再进行后续相关屏幕属性信息查询和事件/状态变化监听
48```
49
50## 获取屏幕相关属性
51
521. 确保获取到Display对象之后(具体可见[获取Display对象](#获取display对象)),可以通过相关属性查询屏幕的一些基础信息。
53
54   ```ts
55   import { display } from '@kit.ArkUI';
56
57   let displayClass: display.Display | null = null;
58   displayClass = display.getDefaultDisplaySync();
59
60   // 获取屏幕Id
61   console.info(`The scree Id is ${displayClass.id}.`);
62   // 获取屏幕刷新率
63   console.info(`The screen is ${displayClass.refreshRate}.`);
64   // 获取屏幕宽度
65   console.info(`The screen width is ${displayClass.width}.`);
66   // 获取屏幕高度
67   console.info(`The screen height is ${displayClass.height}.`);
68   // ...
69   ```
70
712. 还可以通过getCutoutInfo()获取挖孔屏、刘海屏、瀑布屏等不可用的屏幕区域信息,以在UI布局时更好地规避该区域。也可以通过getAvailableArea()获取当前设备屏幕的可用区域。
72
73   ```ts
74   import { BusinessError } from '@kit.BasicServicesKit';
75
76   displayClass.getCutoutInfo().then((cutoutInfo: display.CutoutInfo) => {
77     console.info('Succeeded in getting cutoutInfo. Data: ' + JSON.stringify(cutoutInfo));
78   }).catch((err: BusinessError) => {
79     console.error(`Failed to obtain all the display objects. Code: ${err.code}, message: ${err.message}`);
80   });
81
82   displayClass.getAvailableArea().then((availableArea) => {
83     console.info('Succeeded get the available area in this display. data: ' + JSON.stringify(availableArea));
84   }).catch((err: BusinessError) => {
85     console.error(`Failed to get the available area in this display. Code: ${err.code}, message: ${err.message}`);
86   });
87   ```
88
893. 此外,还可以通过display.isCaptured()判断当前设备是都正在截屏、投屏或录屏。
90
91   ```ts
92   console.info(`The sceeen is captured or not : ${display.isCaptured()}`);
93   ```
94
95## 监听屏幕状态变化
96
971. 可以通过display.on('add'|'remove'|'change')监听设备屏幕变化,支持监听屏幕设备的增加、移除和改变等,可以通过display.off('add'|'remove'|'change')关闭对应的监听。
98
99   ```ts
100   import { display } from '@kit.ArkUI';
101   import { Callback } from '@kit.BasicServicesKit';
102
103   let callback1: Callback<number> = (data: number) => {
104     console.info('Listening enabled. Data: ' + JSON.stringify(data));
105   };
106   // 此处以监听显示设备的增加为例
107   display.on("add", callback1);
108
109   // 如果通过on注册多个callback,同时关闭所有callback监听
110   display.off("add");
111   // 关闭单个callback监听
112   display.off('add', callback1);
113   ```
114
1152. 可以通过display.on('captureStatusChange')开启屏幕截屏、投屏或录屏状态变化的监听;可以通过display.off('captureStatusChange')关闭对应的监听。
116
117   ```ts
118   let callback2: Callback<boolean> = (captureStatus: boolean) => {
119       // captureStatus为true表示显示设备开始截屏、投屏或录屏,false表示结束截屏、投屏或录屏
120     console.info('Listening capture status: ' + captureStatus);
121   };
122   // 开启屏幕截屏、投屏、录屏状态变化的监听
123   display.on('captureStatusChange', callback2);
124
125   display.off('captureStatusChange', callback2);
126   ```
127
1283. 此外,还可以通过on('availableAreaChange')监听当前屏幕对象(Display对象)的可用区域变化;可通过on('availableAreaChange')关闭对应的监听。
129
130   ```ts
131   import { Callback } from '@kit.BasicServicesKit';
132   import { display } from '@kit.ArkUI';
133
134   let callback3: Callback<display.Rect> = (data: display.Rect) => {
135     console.info('Listening enabled. Data: ' + JSON.stringify(data));
136   };
137   let displayClass: display.Display | null = null;
138   try {
139     displayClass = display.getDefaultDisplaySync();
140     // 开启当前屏幕可用区域变化的监听
141     displayClass.on("availableAreaChange", callback3);
142   } catch (exception) {
143     console.error(`Failed to register callback. Code: ${exception.code}, message: ${exception.message}`);
144   }
145   // 关闭当前监听
146   displayClass.off("availableAreaChange", callback3);
147   ```
148
149## 监听折叠设备状态变化
150
1511. 可以通过display.isFoldable()接口查询当前设备是不是折叠设备。
152
153   ```
154   import { display } from '@kit.ArkUI';
155
156   let ret: boolean = false;
157   ret = display.isFoldable();
158   ```
159
1602. 若当前设备为折叠设备,可以通过display.on('foldStatusChange')开启折叠设备折叠状态变化的监听;可通过display.on('foldStatusChange')关闭对应的监听。
161
162   ```ts
163   import { Callback } from '@kit.BasicServicesKit';
164
165   /**
166    * 注册监听的callback参数要采用对象传递.
167    * 若使用匿名函数注册,每次调用会创建一个新的底层对象,引起内存泄漏问题。
168   */
169   let callback: Callback<display.FoldStatus> = (data: display.FoldStatus) => {
170     console.info('Listening enabled. Data: ' + JSON.stringify(data));
171   };
172   display.on('foldStatusChange', callback);
173
174   // 如果通过on注册多个callback,同时关闭所有callback监听
175   display.off('foldStatusChange');
176   // 关闭单个callback监听
177   display.off('foldStatusChange', callback);
178   ```