鸿蒙开发:loading动画的几种实现方式

前言

本文基于Api13

这两天在优化一些功能,发现之前网路库中的oading动画是通过帧动画实现的,而刷新库中的动画却是直接使用的GIF,而到了另一个项目中则又是通过属性动画的方式实现的,索性就针对这几种实现方式简单总结一下,希望可以帮助到有需要的朋友。

首先,我们要知道一点,想要实现一个动态的图片,不仅仅是以上的几种方式,使用lottie也可以实现,所以在实际的开发中,应当根据自身需求需要,选择一种合适的即可。

GIF的实现方式

GIF无疑是实现动态图片的最简单的方式,只需要一个GIF图片便可以搞定,这种方式也是最省心省力的。

只需要把loading的GIF图给Image组件设置即可:

TypeScript 复制代码
Column() {
        Image($r("app.media.loading"))
          .width(40)
          .height(40)
        Text("加载中...")
          .margin({ top: 20 })
      }
      .width(130)
      .height(130)
      .backgroundColor(Color.White)
      .borderRadius(10)
      .justifyContent(FlexAlign.Center)

效果如下:

如果你需要控制GIF的播放速度以及暂停,继续播放等动作,可以结合官方推荐的开源库ohos-gif-drawable来实现。

帧动画

帧动画,可以使用ohos.animator来实现,但是我们也可以使用帧动画组件ImageAnimator来实现,它可以实现逐帧播放图片的能力,仅配置需要播放的图片列表就可以轻松完成一个图片的动画效果。

要想实现帧动画的无限次播放,需要设置iterations属性为-1,在组件挂载显示后进行运行帧动画,在组件卸载消失时停止掉针动画。

定义数据

TypeScript 复制代码
 @State state: AnimationStatus = AnimationStatus.Initial
  private images: Array<ImageFrameInfo> = [
    { src: $r("app.media.loading001") },
    { src: $r("app.media.loading002") },
    { src: $r("app.media.loading003") },
    { src: $r("app.media.loading004") },
    { src: $r("app.media.loading005") },
    { src: $r("app.media.loading006") },
    { src: $r("app.media.loading007") },
    { src: $r("app.media.loading008") },
    { src: $r("app.media.loading009") },
    { src: $r("app.media.loading010") },
    { src: $r("app.media.loading011") },
    { src: $r("app.media.loading012") }
  ]

代码实现

TypeScript 复制代码
Column() {
        ImageAnimator()
          .images(this.images)
          .state(this.state)
          .fixedSize(true)
          .fillMode(FillMode.None)
          .iterations(-1)
          .width(40)
          .height(40)
        Text("加载中...")
          .margin({ top: 20 })
          .fontColor(Color.White)
      }
      .width(130)
      .height(130)
      .backgroundColor("#80000000")
      .borderRadius(10)
      .justifyContent(FlexAlign.Center)
      .onAppear(() => {
        this.state = AnimationStatus.Running
      })
      .onDisAppear(() => {
        this.state = AnimationStatus.Stopped
      })

运行之后,效果如下:

属性动画

使用属性动画就比较简单了,只需要一张静态的图片便可以搞定,让图片360度无限次旋转即可,需要注意的是,改变旋转角度的属性,应定义在组件加载完成之后,相关代码如下:

TypeScript 复制代码
@Entry
@Component
struct Index {
  @State rotateValue: number = 0

  build() {
    Column() {

      Column() {
        Image($r('app.media.loading001'))
          .rotate({ angle: this.rotateValue })
          .width(40)
          .height(40)
          .rotate({
            angle: this.rotateValue
          })
          .animation({
            duration: 1000,
            iterations: -1,
            playMode: PlayMode.Normal,
            curve: Curve.Linear
          })

        Text("加载中...")
          .margin({ top: 20 })
          .fontColor(Color.White)
      }
      .width(130)
      .height(130)
      .backgroundColor("#80000000")
      .borderRadius(10)
      .justifyContent(FlexAlign.Center)
      .onAppear(() => {
        this.rotateValue = 360
      })

    }.width('100%')
    .height("100%")
    .justifyContent(FlexAlign.Center)

  }

}

以上的代码和上面的效果差不多,但是需要控制播放的速度,可以通过animation中的duration来控制。

显式动画

以上的效果,我们也可以使用animateTo显示动画来实现,基本参数和属性动画类似,实现方式如下:

TypeScript 复制代码
@Entry
@Component
struct Index {
  @State rotateValue: number = 0

  build() {
    Column() {

      Column() {
        Image($r('app.media.loading001'))
          .rotate({ angle: this.rotateValue })
          .width(40)
          .height(40)
        Text("加载中...")
          .margin({ top: 20 })
          .fontColor(Color.White)
      }
      .width(130)
      .height(130)
      .backgroundColor("#80000000")
      .borderRadius(10)
      .justifyContent(FlexAlign.Center)

    }.width('100%')
    .height("100%")
    .justifyContent(FlexAlign.Center)

  }

  onDidBuild(): void {
    animateTo({
      duration: 1000,
      iterations: -1,
      playMode: PlayMode.Normal,
      curve: Curve.Linear
    }, () => {
      this.rotateValue = 360
    })
  }
}

相关总结

基本上没什么难的,都是非常简单的动画实现,虽然是一个loading动画,但是也可以应用与其他需要动画的地方。

本文标签:HarmonyOS/ArkUI

相关推荐
冬奇Lab6 分钟前
Android 15音频子系统(五):AudioPolicyService策略管理深度解析
android·音视频开发·源码阅读
亚历克斯神31 分钟前
Flutter for OpenHarmony: Flutter 三方库 mutex 为鸿蒙异步任务提供可靠的临界资源互斥锁(并发安全基石)
android·数据库·安全·flutter·华为·harmonyos
钛态31 分钟前
Flutter 三方库 smartstruct 鸿蒙化字段映射适配指南:介入静态预编译引擎扫除视图及数据模型双向强转类型错乱隐患,筑稳如磐石的企业级模型治理防线-适配鸿蒙 HarmonyOS ohos
flutter·华为·harmonyos
键盘鼓手苏苏31 分钟前
Flutter 组件 csv2json 适配鸿蒙 HarmonyOS 实战:高性能异构数据转换,构建 CSV 流式解析与全栈式数据映射架构
flutter·harmonyos·鸿蒙·openharmony
雷帝木木33 分钟前
Flutter 三方库 hrk_logging 的鸿蒙化适配指南 - 实现标准化分层日志记录、支持多目的地输出与日志分级过滤
flutter·harmonyos·鸿蒙·openharmony·hrk_logging
左手厨刀右手茼蒿36 分钟前
Flutter 三方库 dio_compatibility_layer 的鸿蒙化适配指南 - 实现 Dio 跨主版本的平滑迁移、支持遗留拦截器兼容与网络请求架构稳定升级
flutter·harmonyos·鸿蒙·openharmony·dio_compatibility_layer
雷帝木木40 分钟前
Flutter 三方库 hashids2 基于鸿蒙安全内核的深度隐匿映射适配:数字指纹泄露防御层、生成短小精悍唯一不可逆加盐哈希,护航全链路请求 URL 隐私-适配鸿蒙 HarmonyOS ohos
安全·flutter·harmonyos
dalancon2 小时前
SurfaceControl 的事务提交给 SurfaceFlinger,以及 SurfaceFlinger 如何将这些数据设置到对应 Layer 的完整流程
android
dalancon2 小时前
SurfaceFlinger Layer 到 HWC 通信流程详解
android
HwJack202 小时前
HarmonyOS响应式布局与窗口监听:让界面像呼吸般灵动的艺术
ubuntu·华为·harmonyos