harmony 鸿蒙合理使用动画

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

合理使用动画

本文列举了部分用于优化动画时延的正反案例,帮助开发者在遇到相似场景时进行优化,解决构建页面动画时遇到动画时延较长的问题。

减少动画丢帧

在播放动画或者生成动画时,画面产生停滞而导致帧率过低的现象,称为动画丢帧。

播放动画时,系统需要在一个刷新周期内完成动画变化曲线的计算,完成组件布局绘制等操作。建议使用系统提供的动画接口,只需设置曲线类型、终点位置、时长等信息,就能够满足常用的动画功能,减少UI主线程的负载。

反例:应用使用了自定义动画,动画曲线计算过程很容易引起UI线程高负载,易导致丢帧。

@Entry
@Component
struct AttrAnimationExample0 {
  @State widthSize: number = 200;
  @State heightSize: number = 100;
  @State flag: boolean = true;

  computeSize() {
    let duration = 2000;
    let period = 16;
    let widthSizeEnd = 0;
    let heightSizeEnd = 0;
    if (this.flag) {
      widthSizeEnd = 100;
      heightSizeEnd = 50;
    } else {
      widthSizeEnd = 200;
      heightSizeEnd = 100;
    }
    let doTimes = duration / period;
    let deltaHeight = (heightSizeEnd - this.heightSize) / doTimes;
    let deltaWeight = (widthSizeEnd - this.widthSize) / doTimes;
    for (let i = 1; i <= doTimes; i++) {
      let t = period * (i);
      setTimeout(() => {
        this.heightSize = this.heightSize + deltaHeight;
        this.widthSize = this.widthSize + deltaWeight;
      }, t)
    }
    this.flag = !this.flag;
  }

  build() {
    Column() {
      Button('click me')
        .onClick(() => {
          let delay = 500
          setTimeout(() => { this.computeSize(); }, delay);
        })
        .width(this.widthSize).height(this.heightSize).backgroundColor(0x317aff)
    }.width('100%').margin({ top: 5 })
  }
}

img

使用系统提供的属性动效API

建议:通过系统提供的属性动效API实现上述动效功能。

@Entry
@Component
struct AttrAnimationExample1 {
  @State widthSize: number = 200;
  @State heightSize: number = 100;
  @State flag: boolean = true;

  build() {
    Column() {
      Button('click me')
        .onClick((event?: ClickEvent|undefined) => {
          if (this.flag) {
            this.widthSize = 100;
            this.heightSize = 50;
          } else {
            this.widthSize = 200;
            this.heightSize = 100;
          }
          this.flag = !this.flag;
        })
        .width(this.widthSize).height(this.heightSize).backgroundColor(0x317aff)
        .animation({
          duration: 2000, // 动画时长
          curve: Curve.Linear, // 动画曲线
          delay: 500, // 动画延迟
          iterations: 1, // 播放次数
          playMode: PlayMode.Normal // 动画模式
        }) // 对Button组件的宽高属性进行动画配置
    }.width('100%').margin({ top: 5 })
  }
}

img

更详细的API文档请参考:属性动画

使用系统提供的显式动效API

建议:通过系统提供的显式动效API实现上述动效功能。

@Entry
@Component
struct AnimateToExample2 {
  @State widthSize: number = 200;
  @State heightSize: number = 100;
  @State flag: boolean = true;

  build() {
    Column() {
      Button('click me')
        .onClick((event?: ClickEvent|undefined) => {
          if (this.flag) {
            this.getUIContext().animateTo({
              duration: 2000, // 动画时长
              curve: Curve.Linear, // 动画曲线
              delay: 500, // 动画延迟
              iterations: 1, // 播放次数
              playMode: PlayMode.Normal // 动画模式
            }, () => {
              this.widthSize = 100;
              this.heightSize = 50;
            });
          } else {
            this.getUIContext().animateTo({
              duration: 2000, // 动画时长
              curve: Curve.Linear, // 动画曲线
              delay: 500, // 动画延迟
              iterations: 1, // 播放次数
              playMode: PlayMode.Normal // 动画模式
            }, () => {
              this.widthSize = 200;
              this.heightSize = 100;
            });
          }
          this.flag = !this.flag;
        })
        .width(this.widthSize).height(this.heightSize).backgroundColor(0x317aff)
    }.width('100%').margin({ top: 5 })
  }
}

img

更详细的API文档请参考:显式动画

优化效果

相比于自定义动画,使用系统提供的动效API可提高动画帧数,提高应用性能。

动画实现方式 帧数(fps)
自定义动画 60
属性动效API 120
显式动效API 120

合理设置隐式动画

Tabs组件在不为BottomTabBarStyle样式时,切换页面时默认加载300ms的隐式动画,如果开发场景不需要该动画效果,会因默认加载导致页面跳转完成时延变长,此时可手动设置animationDuration减少动画完成时延。下述正反示例分别为100ms和1000ms的动画时延:

反例:

@Entry
@Component
struct TabsExample {
  // ...
  private controller: TabsController = new TabsController();

  build() {
    Column() {
      Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {
        TabContent()
        TabContent()
        // ...
      }
      // ...
      // 设置Tabs页面跳转的动画时长为1000ms
      .animationDuration(1000)
    }
    .width('100%')
  }
}

img

正例:

@Entry
@Component
struct TabsExample {
  // ...
  private controller: TabsController = new TabsController();

  build() {
    Column() {
      Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {
        TabContent()
        TabContent()
        // ...
      }
      // ...
      // 设置Tabs页面跳转的动画时长为100ms
      .animationDuration(100)
    }
    .width('100%')
  }
}

img

优化效果

|优化前 1000ms |优化后 100ms |
|—————————————————-|—————————————————-| |img|img|

上述示例通过减少animationDuration数值,减少Tabs切换完成时延。当数值设置为0且TabBar不为BottomTabBarStyle样式时,隐式动效延时为默认的300ms。开发者可根据实际场景适当减少隐式动效时延,如果应用没有特殊的动效要求时,建议设置数值为1,减少阻塞主线程,提高应用性能。

更详细的API文档请参考:Tabs-animationduration

合理设置动效时长

滚动类组件可使用fling方法按传入的初始速度进行惯性滚动,不合理的滚动速度设置可能导致动效时长过长,此时应通过加快滚动速度减少动效时长。下述正反示例通过改变List组件惯性滚动速度减少动效时长:

反例:

@Entry
@Component
struct ListExample {
  scrollerForList: Scroller = new Scroller();

  build() {
    Column() {
      Button('Fling100')
        .onClick(() => {
          // 设置当前滚动初始速度为100vp/s
          this.scrollerForList.fling(100);
        })
      List({ space: 20, initialIndex: 0, scroller: this.scrollerForList }) {
        // ...
      }
    }
  }
}

正例:

@Entry
@Component
struct ListExample {
  scrollerForList: Scroller = new Scroller();

  build() {
    Column() {
      Button('Fling100')
        .onClick(() => {
          // 设置当前滚动初始速度为10000vp/s
          this.scrollerForList.fling(10000);
        })
      List({ space: 20, initialIndex: 0, scroller: this.scrollerForList }) {
        // ...
      }
    }
  }
}

优化效果

100vp/s:

img

10000vp/s:

img

示例 动效耗时(ms)
优化前 392
优化后 200

上述示例在提高滚动速度到10000vp/s后,相比100vp/s减少了200ms的动画时延。开发者可根据实际场景适当增加滚动速度,在不影响页面效果的情况下减少页面完成时延,提高应用性能。

你可能感兴趣的鸿蒙文章

harmony 鸿蒙延迟加载lazy-import使用指导

harmony 鸿蒙性能

harmony 鸿蒙应用程序动效能力实践

harmony 鸿蒙应用性能分析工具CPU Profiler的使用指导

harmony 鸿蒙应用性能问题分析指导

harmony 鸿蒙应用开发性能优化入门引导

harmony 鸿蒙页面布局检查器ArkUI Inspector使用指导

harmony 鸿蒙性能提升的其他方法

harmony 鸿蒙音画同步最佳实践

harmony 鸿蒙避免在滑动场景的高频回调接口中处理耗时操作

0  赞