十八、【鸿蒙 NEXT】实现图片动画
鸿蒙开发中实现图片动画的两种方案:1)使用Image组件配合AnimatedDrawableDescriptor对象,通过循环加载图片资源生成PixelMap数组;2)使用ImageAnimator组件直接传入图片路径数组,但存在持续解析图片导致性能损耗和日志冲刷问题,建议预先解析为PixelMap再传入组件。两种方式都能实现循环播放动画效果,但ImageAnimator需要额外处理性能优化问题。
【前言】
在安卓开发中,使用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组件没有啥区别

更多推荐



所有评论(0)