【前言】

在安卓开发中,使用ImageView组件可以加载xml文件,来实现一组图片动画的效果,而鸿蒙next框架中的Image组件无法加载xml文件。下面介绍下两种加载一组图片,实现动画的效果。

一、使用Image组件

Image组件支持传入DrawableDescriptor对象,其中AnimatedDrawableDescriptor对象是其子类,可以通过构造AnimatedDrawableDescriptor对象来实现动画效果,代码如下

import { AnimatedDrawableDescriptor } from '@kit.ArkUI'

@Entry
@Component
struct AnimalPage {
  @State imgs:AnimatedDrawableDescriptor | null = null

  aboutToAppear(): void {
    let pixelMaps:PixelMap[] = []
    for (let i = 0 ;i<4;i++) {
      let resName = `loading_${i.toString().padStart(4,'0')}`
      let pixelMap = getContext().resourceManager.getDrawableDescriptorByName(resName).getPixelMap()
      pixelMaps.push(pixelMap)
    }
    this.imgs = new AnimatedDrawableDescriptor(pixelMaps, {duration:3000, iterations: -1})
  }

  build() {
    Column(){
      Image(this.imgs)
        .height(48)
        .width(48)
    }
  }
}

其中需要加载的图片在resource/base/media路径下,图片名称如下图,在代码中通过循环构造图片名称加载图片,获取图片的PixelMap对象

二、使用ImageAnimator组件

ImageAnimator组件支持传入ImageFrameInfo[]数组,其中ImageFrameInfo对象支持传入图片的字符串路径,图片的resource对象,或者PixelMap对象,相对Image组件支持的类型更多,代码如下,其中state = Runnig表示自动播放,iteration = -1表示无限循环播放。

@Entry
@Component
struct ImageAnimatorPage {
  @State imgs: ImageFrameInfo[] = []

  aboutToAppear(): void {
    let frameInfos: ImageFrameInfo[] = []
    for (let i = 0; i < 4; i++) {
      frameInfos.push({ src: $r(`app.media.loading_${i.toString().padStart(4, '0')}`), duration: 1000 })
    }
    this.imgs = frameInfos
  }

  build() {
    Column() {
      ImageAnimator()
        .images(this.imgs)
        .state(AnimationStatus.Running)
        .iterations(-1)
        .height(48)
        .width(48)
    }
    .height('100%')
    .width('100%')
  }
}

这里使用ImageAnimator组件时,有个小问题,如果一直循环播放,hilog会一直打印图片解析的日志,因为底层ImageAnimator组件还是会把图片资源解析为PixelMap对象,组件本身不会缓存该对象,会一直循环解析,影响一定的性能。另一方面不停的打印日志会冲刷掉正常业务日志,如果业务依赖系统hilog日志定位问题,会有一定影响,循环打印的日志如下,解决方案就是先自己提前将图片解析为PixelMap对象后,再传给组件,这就和使用Image组件没有啥区别

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐