• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 请求UI绘制帧率
2<!--Kit: ArkGraphics 2D-->
3<!--Subsystem: Graphics-->
4<!--Owner: @hudi33-->
5<!--Designer: @hudi33-->
6<!--Tester: @zhaoxiaoguang2-->
7<!--Adviser: @ge-yafang-->
8
9如果开发者需要以独立的帧率绘制更新操作UI界面时,可以通过DisplaySync来实现。应用中绘制内容的帧率可以使用DisplaySync实例来控制,具体请查阅[@ohos.graphics.displaySync(可变帧率)](../reference/apis-arkgraphics2d/js-apis-graphics-displaySync.md)。
10
11## 开发步骤
12
13此处以不同帧率改变文件组件字体大小为例,来模拟不同UI绘制帧率的效果。
14
151. 导入模块。
16
17   ```ts
18   import { displaySync } from '@kit.ArkGraphics2D';
19   ```
20
212. 定义和构建DisplaySync对象。
22
23   ```ts
24   @Entry
25   @Component
26   struct Index {
27     // 定义两个DisplaySync变量,未初始化
28     private backDisplaySyncSlow: displaySync.DisplaySync | undefined = undefined;
29     private backDisplaySyncFast: displaySync.DisplaySync | undefined = undefined;
30   }
31   ```
32
333. 定义两个文本组件。
34
35   ```ts
36   @State drawFirstSize: number = 25;
37   @State drawSecondSize: number = 25;
38   @Builder doSomeRenderFirst() {
39    Text('30')
40      .fontSize(this.drawFirstSize)
41   }
42
43   @Builder doSomeRenderSecond() {
44    Text('60')
45      .fontSize(this.drawSecondSize)
46   }
47   ```
48
494. 通过DisplaySync实例设置帧率和注册订阅函数。
50
51   > **说明:**
52   >
53   > 订阅函数运行于UI主线程,故涉及UI线程的耗时操作不应运行于订阅函数中,以免影响性能。
54
55   ```ts
56   CreateDisplaySyncSlow() {
57       let range : ExpectedFrameRateRange = { // 创建和配置帧率参数
58         expected: 30, // 设置期望绘制帧率为30hz
59         min: 0, // 配置帧率范围
60         max: 120 // 配置帧率范围
61       };
62
63       let draw30 = (intervalInfo: displaySync.IntervalInfo) => { // 订阅回调函数,字体大小在25到150之间变化
64         if (this.isBigger_30) {
65           this.drawFirstSize += 1;
66           if (this.drawFirstSize > 150) {
67             this.isBigger_30 = false;
68           }
69         } else {
70           this.drawFirstSize -= 1;
71           if (this.drawFirstSize < 25) {
72             this.isBigger_30 = true;
73           }
74         }
75       };
76
77       this.backDisplaySyncSlow = displaySync.create(); // 创建DisplaySync实例
78       this.backDisplaySyncSlow.setExpectedFrameRateRange(range); // 设置帧率
79       this.backDisplaySyncSlow.on("frame", draw30); // 订阅frame事件和注册订阅函数
80   }
81   ```
82
835. 开始每帧回调。
84
85   ```ts
86   Button('Start')
87     .id('CustomDrawStart')
88     .fontSize(14)
89     .fontWeight(500)
90     .margin({ bottom: 10, left: 5 })
91     .fontColor(Color.White)
92     .onClick((): void => {
93         if (this.backDisplaySyncSlow == undefined) {
94           this.CreateDisplaySyncSlow();
95         }
96         if (this.backDisplaySyncFast == undefined) {
97           this.CreateDisplaySyncFast();
98         }
99         if (this.backDisplaySyncSlow) {
100           this.backDisplaySyncSlow.start();
101         }
102         if (this.backDisplaySyncFast) {
103           this.backDisplaySyncFast.start();
104         }
105       })
106       .width('20%')
107       .height(40)
108       .shadow(ShadowStyle.OUTER_DEFAULT_LG)
109   ```
110
111   > **说明:**
112   >
113   > 创建的DisplaySync实例在start使能后需要aboutToDisappear函数中进行stop操作并置空,避免内存泄漏问题。
114   ```ts
115   aboutToDisappear() {
116     if (this.backDisplaySyncSlow) {
117       this.backDisplaySyncSlow.stop();
118       this.backDisplaySyncSlow = undefined;
119     }
120     if (this.backDisplaySyncFast) {
121       this.backDisplaySyncFast.stop();
122       this.backDisplaySyncFast = undefined;
123     }
124   }
125   ```
126
1276. 结束每帧回调。
128
129   ```ts
130   Button('Stop')
131     .id('CustomDrawStop')
132     .fontSize(14)
133     .fontWeight(500)
134     .margin({ bottom: 10, left: 5 })
135     .fontColor(Color.White)
136     .onClick((): void => {
137       if (this.backDisplaySyncSlow) {
138           this.backDisplaySyncSlow.stop();
139       }
140       if (this.backDisplaySyncFast) {
141           this.backDisplaySyncFast.stop();
142       }
143     })
144     .width('20%')
145     .height(40)
146     .shadow(ShadowStyle.OUTER_DEFAULT_LG)
147   ```
148
149## 完整示例
150```ts
151import { displaySync } from '@kit.ArkGraphics2D';
152
153@Entry
154@Component
155struct Index {
156  @State drawFirstSize: number = 25;
157  @State drawSecondSize: number = 25;
158  private backDisplaySyncSlow: displaySync.DisplaySync | undefined = undefined;
159  private backDisplaySyncFast: displaySync.DisplaySync | undefined = undefined;
160  private isBigger_30:boolean = true;
161  private isBigger_60:boolean = true;
162
163  @Builder doSomeRenderFirst() {
164    Text('30')
165      .fontSize(this.drawFirstSize)
166  }
167
168  @Builder doSomeRenderSecond() {
169    Text('60')
170      .fontSize(this.drawSecondSize)
171  }
172
173  CreateDisplaySyncSlow() {
174    // 定义期望绘制帧率
175    let range : ExpectedFrameRateRange = {
176      expected: 30,
177      min: 0,
178      max: 120
179    };
180
181    let draw30 = (intervalInfo: displaySync.IntervalInfo) => {
182      if (this.isBigger_30) {
183        this.drawFirstSize += 1;
184        if (this.drawFirstSize > 150) {
185          this.isBigger_30 = false;
186        }
187      } else {
188        this.drawFirstSize -= 1;
189        if (this.drawFirstSize < 25) {
190          this.isBigger_30 = true;
191        }
192      }
193    };
194
195    this.backDisplaySyncSlow = displaySync.create(); // 创建DisplaySync实例
196    this.backDisplaySyncSlow.setExpectedFrameRateRange(range); // 设置帧率
197    this.backDisplaySyncSlow.on("frame", draw30); // 订阅frame事件和注册订阅函数
198  }
199
200  CreateDisplaySyncFast() {
201    // 定义期望绘制帧率
202    let range : ExpectedFrameRateRange = {
203      expected: 60,
204      min: 0,
205      max: 120
206    };
207
208    let draw60 = (intervalInfo: displaySync.IntervalInfo) => {
209      if (this.isBigger_60) {
210        this.drawSecondSize += 1;
211        if (this.drawSecondSize > 150) {
212          this.isBigger_60 = false;
213        }
214      } else {
215        this.drawSecondSize -= 1;
216        if (this.drawSecondSize < 25) {
217          this.isBigger_60 = true;
218        }
219      }
220
221    };
222
223    this.backDisplaySyncFast= displaySync.create(); // 创建DisplaySync实例
224    this.backDisplaySyncFast.setExpectedFrameRateRange(range); // 设置帧率
225    this.backDisplaySyncFast.on("frame", draw60); // 订阅frame事件和注册订阅函数
226  }
227
228  aboutToDisappear() {
229    if (this.backDisplaySyncSlow) {
230      this.backDisplaySyncSlow.stop(); // DisplaySync失能关闭
231      this.backDisplaySyncSlow = undefined; // 实例置空
232    }
233    if (this.backDisplaySyncFast) {
234      this.backDisplaySyncFast.stop(); // DisplaySync失能关闭
235      this.backDisplaySyncFast = undefined; // 实例置空
236    }
237  }
238
239  build() {
240    Column() {
241      Row() {
242        this.doSomeRenderFirst();
243      }
244      .height('40%')
245
246      Row() {
247        this.doSomeRenderSecond();
248      }
249      .height('40%')
250
251      Row() {
252        Button('Start')
253          .id('CustomDrawStart')
254          .fontSize(14)
255          .fontWeight(500)
256          .margin({ bottom: 10, left: 5 })
257          .fontColor(Color.White)
258          .onClick((): void => {
259            if (this.backDisplaySyncSlow == undefined) {
260              this.CreateDisplaySyncSlow();
261            }
262            if (this.backDisplaySyncFast == undefined) {
263              this.CreateDisplaySyncFast();
264            }
265            if (this.backDisplaySyncSlow) {
266              this.backDisplaySyncSlow.start(); // DisplaySync使能开启
267            }
268            if (this.backDisplaySyncFast) {
269              this.backDisplaySyncFast.start(); // DisplaySync使能开启
270            }
271          })
272          .width('20%')
273          .height(40)
274          .shadow(ShadowStyle.OUTER_DEFAULT_LG)
275
276        Button('Stop')
277          .id('CustomDrawStop')
278          .fontSize(14)
279          .fontWeight(500)
280          .margin({ bottom: 10, left: 5 })
281          .fontColor(Color.White)
282          .onClick((): void => {
283            if (this.backDisplaySyncSlow) {
284              this.backDisplaySyncSlow.stop(); // DisplaySync失能关闭
285            }
286            if (this.backDisplaySyncFast) {
287              this.backDisplaySyncFast.stop(); // DisplaySync失能关闭
288            }
289          })
290          .width('20%')
291          .height(40)
292          .shadow(ShadowStyle.OUTER_DEFAULT_LG)
293      }
294      .width('100%')
295      .justifyContent(FlexAlign.Center)
296      .shadow(ShadowStyle.OUTER_DEFAULT_SM)
297      .alignItems(VerticalAlign.Bottom)
298      .layoutWeight(1)
299    }
300  }
301}
302```
303
304<!--RP1-->
305## 相关实例
306
307- [DisplaySync (API14)](https://gitcode.com/openharmony/applications_app_samples/tree/master/code/DocsSample/graphic/DisplaySync)
308<!--RP1End-->