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-->