harmony 鸿蒙请求UI绘制帧率

  • 2025-06-12
  • 浏览 (6)

请求UI绘制帧率

如果开发者需要以独立的帧率绘制更新操作UI界面时,可以通过DisplaySync来实现。应用中绘制内容的帧率可以使用DisplaySync实例来控制,具体请查阅@ohos.graphics.displaySync(可变帧率)

开发步骤

此处以不同帧率改变文件组件字体大小为例,来模拟不同UI绘制帧率的效果。

  1. 导入模块。
   import { displaySync } from '@kit.ArkGraphics2D';
  1. 定义和构建DisplaySync对象。
   @Entry
   @Component
   struct Index {
     // 定义两个DisplaySync变量,未初始化
     private backDisplaySyncSlow: displaySync.DisplaySync|undefined = undefined;
     private backDisplaySyncFast: displaySync.DisplaySync|undefined = undefined;
   }
  1. 定义两个文本组件。
   @State drawFirstSize: number = 25;
   @State drawSecondSize: number = 25;
   @Builder doSomeRenderFirst() {
    Text('30')
      .fontSize(this.drawFirstSize)
   }
   
   @Builder doSomeRenderSecond() {
    Text('60')
      .fontSize(this.drawSecondSize)
   }
  1. 通过DisplaySync实例设置帧率和注册订阅函数。

说明:

订阅函数运行于UI主线程,故涉及UI线程的耗时操作不应运行于订阅函数中,以免影响性能。

   CreateDisplaySyncSlow() {
       let range : ExpectedFrameRateRange = { // 创建和配置帧率参数
         expected: 30, // 设置期望绘制帧率为30hz
         min: 0, // 配置帧率范围
         max: 120 // 配置帧率范围
       };
   
       let draw30 = (intervalInfo: displaySync.IntervalInfo) => { // 订阅回调函数,字体大小在25到150之间变化
         if (this.isBigger_30) {
           this.drawFirstSize += 1;
           if (this.drawFirstSize > 150) {
             this.isBigger_30 = false;
           }
         } else {
           this.drawFirstSize -= 1;
           if (this.drawFirstSize < 25) {
             this.isBigger_30 = true;
           }
         }
       };
   
       this.backDisplaySyncSlow = displaySync.create(); // 创建DisplaySync实例
       this.backDisplaySyncSlow.setExpectedFrameRateRange(range); // 设置帧率
       this.backDisplaySyncSlow.on("frame", draw30); // 订阅frame事件和注册订阅函数
   }
  1. 开始每帧回调。
   Button('Start')
     .id('CustomDrawStart')
     .fontSize(14)
     .fontWeight(500)
     .margin({ bottom: 10, left: 5 })
     .fontColor(Color.White)
     .onClick((): void => {
         if (this.backDisplaySyncSlow == undefined) {
           this.CreateDisplaySyncSlow();
         }
         if (this.backDisplaySyncFast == undefined) {
           this.CreateDisplaySyncFast();
         }
         if (this.backDisplaySyncSlow) {
           this.backDisplaySyncSlow.start();
         }
         if (this.backDisplaySyncFast) {
           this.backDisplaySyncFast.start();
         }
       })
       .width('20%')
       .height(40)
       .shadow(ShadowStyle.OUTER_DEFAULT_LG)

说明:

创建的DisplaySync实例在start使能后需要aboutToDisappear函数中进行stop操作并置空,避免内存泄漏问题。

   aboutToDisappear() {
     if (this.backDisplaySyncSlow) {
       this.backDisplaySyncSlow.stop();
       this.backDisplaySyncSlow = undefined;
     }
     if (this.backDisplaySyncFast) {
       this.backDisplaySyncFast.stop();
       this.backDisplaySyncFast = undefined;
     }
   }
  1. 结束每帧回调。
   Button('Stop')
     .id('CustomDrawStop')
     .fontSize(14)
     .fontWeight(500)
     .margin({ bottom: 10, left: 5 })
     .fontColor(Color.White)
     .onClick((): void => {
       if (this.backDisplaySyncSlow) {
           this.backDisplaySyncSlow.stop();
       }
       if (this.backDisplaySyncFast) {
           this.backDisplaySyncFast.stop();
       }
     })
     .width('20%')
     .height(40)
     .shadow(ShadowStyle.OUTER_DEFAULT_LG)

完整示例

import { displaySync } from '@kit.ArkGraphics2D';

@Entry
@Component
struct Index {
  @State drawFirstSize: number = 25;
  @State drawSecondSize: number = 25;
  private backDisplaySyncSlow: displaySync.DisplaySync|undefined = undefined;
  private backDisplaySyncFast: displaySync.DisplaySync|undefined = undefined;
  private isBigger_30:boolean = true;
  private isBigger_60:boolean = true;

  @Builder doSomeRenderFirst() {
    Text('30')
      .fontSize(this.drawFirstSize)
  }

  @Builder doSomeRenderSecond() {
    Text('60')
      .fontSize(this.drawSecondSize)
  }

  CreateDisplaySyncSlow() {
    // 定义期望绘制帧率
    let range : ExpectedFrameRateRange = {
      expected: 30,
      min: 0,
      max: 120
    };

    let draw30 = (intervalInfo: displaySync.IntervalInfo) => {
      if (this.isBigger_30) {
        this.drawFirstSize += 1;
        if (this.drawFirstSize > 150) {
          this.isBigger_30 = false;
        }
      } else {
        this.drawFirstSize -= 1;
        if (this.drawFirstSize < 25) {
          this.isBigger_30 = true;
        }
      }
    };

    this.backDisplaySyncSlow = displaySync.create(); // 创建DisplaySync实例
    this.backDisplaySyncSlow.setExpectedFrameRateRange(range); // 设置帧率
    this.backDisplaySyncSlow.on("frame", draw30); // 订阅frame事件和注册订阅函数
  }

  CreateDisplaySyncFast() {
    // 定义期望绘制帧率
    let range : ExpectedFrameRateRange = {
      expected: 60,
      min: 0,
      max: 120
    };

    let draw60 = (intervalInfo: displaySync.IntervalInfo) => {
      if (this.isBigger_60) {
        this.drawSecondSize += 1;
        if (this.drawSecondSize > 150) {
          this.isBigger_60 = false;
        }
      } else {
        this.drawSecondSize -= 1;
        if (this.drawSecondSize < 25) {
          this.isBigger_60 = true;
        }
      }

    };

    this.backDisplaySyncFast= displaySync.create(); // 创建DisplaySync实例
    this.backDisplaySyncFast.setExpectedFrameRateRange(range); // 设置帧率
    this.backDisplaySyncFast.on("frame", draw60); // 订阅frame事件和注册订阅函数
  }

  aboutToDisappear() {
    if (this.backDisplaySyncSlow) {
      this.backDisplaySyncSlow.stop(); // DisplaySync失能关闭
      this.backDisplaySyncSlow = undefined; // 实例置空
    }
    if (this.backDisplaySyncFast) {
      this.backDisplaySyncFast.stop(); // DisplaySync失能关闭
      this.backDisplaySyncFast = undefined; // 实例置空
    }
  }

  build() {
    Column() {
      Row() {
        this.doSomeRenderFirst();
      }
      .height('40%')

      Row() {
        this.doSomeRenderSecond();
      }
      .height('40%')

      Row() {
        Button('Start')
          .id('CustomDrawStart')
          .fontSize(14)
          .fontWeight(500)
          .margin({ bottom: 10, left: 5 })
          .fontColor(Color.White)
          .onClick((): void => {
            if (this.backDisplaySyncSlow == undefined) {
              this.CreateDisplaySyncSlow();
            }
            if (this.backDisplaySyncFast == undefined) {
              this.CreateDisplaySyncFast();
            }
            if (this.backDisplaySyncSlow) {
              this.backDisplaySyncSlow.start(); // DisplaySync使能开启
            }
            if (this.backDisplaySyncFast) {
              this.backDisplaySyncFast.start(); // DisplaySync使能开启
            }
          })
          .width('20%')
          .height(40)
          .shadow(ShadowStyle.OUTER_DEFAULT_LG)

        Button('Stop')
          .id('CustomDrawStop')
          .fontSize(14)
          .fontWeight(500)
          .margin({ bottom: 10, left: 5 })
          .fontColor(Color.White)
          .onClick((): void => {
            if (this.backDisplaySyncSlow) {
              this.backDisplaySyncSlow.stop(); // DisplaySync失能关闭
            }
            if (this.backDisplaySyncFast) {
              this.backDisplaySyncFast.stop(); // DisplaySync失能关闭
            }
          })
          .width('20%')
          .height(40)
          .shadow(ShadowStyle.OUTER_DEFAULT_LG)
      }
      .width('100%')
      .justifyContent(FlexAlign.Center)
      .shadow(ShadowStyle.OUTER_DEFAULT_SM)
      .alignItems(VerticalAlign.Bottom)
      .layoutWeight(1)
    }
  }
}

相关实例

针对可变帧率的开发,有以下相关实例可供参考:

你可能感兴趣的鸿蒙文章

harmony 鸿蒙ArkGraphics 2D(方舟2D图形服务)

harmony 鸿蒙ArkGraphics 2D简介

harmony 鸿蒙基础绘制效果(ArkTS)

harmony 鸿蒙基础绘制效果(C/C++)

harmony 鸿蒙画布的获取与绘制结果的显示(ArkTS)

harmony 鸿蒙画布的获取与绘制结果的显示(C/C++)

harmony 鸿蒙画布操作及状态处理(ArkTS)

harmony 鸿蒙画布操作及状态处理(C/C++)

harmony 鸿蒙复杂绘制效果(ArkTS)

harmony 鸿蒙复杂绘制效果(C/C++)

0  赞