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