前言
本文基于Api13
這兩天在優(yōu)化一些功能,發(fā)現(xiàn)之前網(wǎng)路庫中的oading動畫是通過幀動畫實現(xiàn)的,而刷新庫中的動畫卻是直接使用的GIF,而到了另一個項目中則又是通過屬性動畫的方式實現(xiàn)的,索性就針對這幾種實現(xiàn)方式簡單總結(jié)一下,希望可以幫助到有需要的朋友。
首先,我們要知道一點,想要實現(xiàn)一個動態(tài)的圖片,不僅僅是以上的幾種方式,使用lottie也可以實現(xiàn),所以在實際的開發(fā)中,應(yīng)當(dāng)根據(jù)自身需求需要,選擇一種合適的即可。
GIF的實現(xiàn)方式
GIF無疑是實現(xiàn)動態(tài)圖片的最簡單的方式,只需要一個GIF圖片便可以搞定,這種方式也是最省心省力的。
只需要把loading的GIF圖給Image組件設(shè)置即可:
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的播放速度以及暫停,繼續(xù)播放等動作,可以結(jié)合官方推薦的開源庫ohos-gif-drawable來實現(xiàn)。
幀動畫
幀動畫,可以使用ohos.animator來實現(xiàn),但是我們也可以使用幀動畫組件ImageAnimator來實現(xiàn),它可以實現(xiàn)逐幀播放圖片的能力,僅配置需要播放的圖片列表就可以輕松完成一個圖片的動畫效果。
要想實現(xiàn)幀動畫的無限次播放,需要設(shè)置iterations屬性為-1,在組件掛載顯示后進(jìn)行運行幀動畫,在組件卸載消失時停止掉針動畫。
定義數(shù)據(jù)
@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") }
]
代碼實現(xiàn)
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
})
運行之后,效果如下:

屬性動畫
使用屬性動畫就比較簡單了,只需要一張靜態(tài)的圖片便可以搞定,讓圖片360度無限次旋轉(zhuǎn)即可,需要注意的是,改變旋轉(zhuǎn)角度的屬性,應(yīng)定義在組件加載完成之后,相關(guān)代碼如下:
@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顯示動畫來實現(xiàn),基本參數(shù)和屬性動畫類似,實現(xiàn)方式如下:
@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
})
}
}
相關(guān)總結(jié)
基本上沒什么難的,都是非常簡單的動畫實現(xiàn),雖然是一個loading動畫,但是也可以應(yīng)用與其他需要動畫的地方。
本文標(biāo)簽:HarmonyOS/ArkUI