HarmonyOS Next 屬性動畫和轉場動畫
在鴻蒙應用開發中,動畫是提升用戶體驗的關鍵要素。通過巧妙運用動畫,我們能讓應用界面更加生動、交互更加流暢,從而吸引用戶的注意力并增強其使用粘性。鴻蒙系統為開發者提供了豐富且強大的動畫開發能力,其中屬性動畫是整個動畫體系的核心基礎。接下來,讓我們深入探索鴻蒙動畫。
鴻蒙動畫體系概覽
鴻蒙動畫體系旨在為開發者打造全方位、多層次的動畫創作環境。它不僅包含屬性動畫這種能夠精確控制組件屬性變化的基礎類型,還擁有轉場動畫,用于實現界面間的平滑過渡,為用戶帶來自然且流暢的視覺切換體驗。無論是組件的移動、旋轉、縮放,還是界面的淡入淡出、滑動切換,鴻蒙動畫體系都能輕松應對,助力開發者創建出極具吸引力的應用界面。
屬性動畫
可動畫屬性的多樣選擇
系統預定義可動畫屬性:鴻蒙系統貼心地為組件提供了一系列內置的可動畫屬性接口。例如,position
屬性能夠精準地調整組件在屏幕上的位置,使組件可以在不同坐標間平滑移動;scale
屬性用于控制組件的縮放比例,讓組件能夠自如地放大或縮小;opacity
屬性則決定了組件的透明度,實現淡入淡出等效果;blur
屬性可賦予組件模糊效果,為界面增添獨特的視覺風格。這些系統預定義的可動畫屬性,極大地簡化了開發者創建常見動畫效果的過程。
分類 | 說明 |
---|---|
布局屬性 | 位置、大小、內邊距、外邊距、對齊方式、權重等。 |
仿射變換 | 平移、旋轉、縮放、錨點等。 |
背景 | 背景顏色、背景模糊等。 |
內容 | 文字大小、文字顏色,圖片對齊方式、模糊等。 |
前景 | 前景顏色等。 |
Overlay | Overlay屬性等。 |
外觀 | 透明度、圓角、邊框、陰影等。 |
自定義可動畫屬性拓展:ArkUI 賦予開發者強大的自定義能力,通過@AnimatableExtend
裝飾器,開發者能夠從自定義繪制的內容中抽象出可動畫屬性。設想在開發一個音樂應用時,需要自定義繪制一個音量圖標,并且希望該圖標能夠根據音量大小動態改變其大小、顏色或形狀。借助@AnimatableExtend
裝飾器,開發者就可以為這個原本不具備默認動畫屬性的自定義圖標添加動畫效果,從而滿足特定的業務需求和創意設計。
豐富的屬性動畫接口
animateTo 接口:該接口主要作用于閉包內改變屬性引起的界面變化,尤其在組件出現和消失的轉場場景中表現出色。其原理是通過對比閉包前界面和閉包中狀態變量引起的界面之間的差異,然后依據設定的動畫參數對這些差異進行動畫處理。它支持多次調用以及嵌套使用,這為開發者在處理復雜動畫邏輯時提供了極大的靈活性。例如,在一個需要讓組件同時進行平移、旋轉和縮放,并且這些動畫都使用相同動畫參數的場景中,animateTo
就能發揮其優勢,簡潔高效地實現所需動畫效果。
animation 接口:animation
接口作用于組件通過屬性接口綁定的屬性變化引起的界面變化。它能夠敏銳地識別組件的可動畫屬性變化,當檢測到綁定的可動畫屬性發生改變時,會自動為這些屬性變化添加動畫效果。值得注意的是,組件的接口調用遵循從下往上的執行順序,animation
只會作用于在其之上的屬性調用。這意味著開發者可以根據組件屬性的調用順序,輕松地對多個屬性設置不同的animation
效果。比如,在一個組件既要移動又要改變透明度,且移動速度和透明度變化速度不同的場景中,通過animation
接口分別為translate
屬性和opacity
屬性設置不同的動畫參數,就能精準實現所需的動畫效果。
代碼示例
下面通過一個具體的代碼示例,展示如何使用animateTo
接口來實現屬性動畫。
@Entry
@Component
@Preview
struct AnimPage {@State animate: boolean = false;// 第一步: 聲明相關狀態變量@State rotateValue: number = 0; // 組件一旋轉角度@State translateX: number = 0; // 組件二偏移量@State opacityValue: number = 1; // 組件二透明度build() {Column({ space: 20 }) {Row() {// 組件一Column() {Text("123")}.rotate({ angle: this.rotateValue }).backgroundColor('#317AF7').justifyContent(FlexAlign.Center).width(100).height(100).borderRadius(30).onClick(() => {this.getUIContext()?.animateTo({ curve: curves.springMotion(), duration: 3500 }, () => {this.animate = !this.animate;// 第三步:閉包內通過狀態變量改變UI界面// 這里可以寫任何能改變UI的邏輯比如數組添加,顯隱控制,系統會檢測改變后的UI界面與之前的UI界面的差異,對有差異的部分添加動畫// 組件一的rotate屬性發生變化,所以會給組件一添加rotate旋轉動畫this.rotateValue = this.animate ? 90 : 0;// 組件二的透明度發生變化,所以會給組件二添加透明度的動畫this.opacityValue = this.animate ? 0.6 : 1;// 組件二的translate屬性發生變化,所以會給組件二添加translate偏移動畫this.translateX = this.animate ? 50 : 0;})})// 組件二Column() {Text("456")}.justifyContent(FlexAlign.Center).width(100).height(100).backgroundColor('#D94838').borderRadius(30).opacity(this.opacityValue).translate({ x: this.translateX }).animation({ curve: curves.springMotion(), duration: 3500 })}.width('100%').justifyContent(FlexAlign.Center)}}
}
在上述代碼中,當用戶點擊Column
組件時,animate
狀態變量會發生改變。依據animate
的值,rotateValue
(旋轉角度)、translateX
(偏移量)和opacityValue
(透明度)這三個狀態變量會相應地改變。由于opacity
、rotate
等屬性綁定了animation
接口,并且設置了彈簧曲線curves.springMotion()
,所以當這些屬性值發生變化時,會自動按照彈簧曲線的規律產生動畫效果,使組件的旋轉、平移和透明度變化呈現出自然的彈簧效果,為用戶帶來獨特而生動的視覺體驗。
效果如下:
轉場動畫
轉場動畫是指對將要出現或消失的組件做動畫,對始終出現的組件做動畫應使用屬性動畫。轉場動畫主要為了讓開發者從繁重的消失節點管理中解放出來,如果用屬性動畫做組件轉場,開發者需要在動畫結束回調中刪除組件節點。同時,由于動畫結束前已經刪除的組件節點可能會重新出現,還需要在結束回調中增加對節點狀態的判斷。
轉場效果 | 說明 | 動畫 |
---|---|---|
IDENTITY | 禁用轉場效果。 | 無。 |
OPACITY | 默認的轉場效果,透明度轉場。 | 出現時透明度從0到1,消失時透明度從1到0。 |
SLIDE | 滑動轉場效果。 | 出現時從窗口左側滑入,消失時從窗口右側滑出。 |
translate | 通過設置組件平移創建轉場效果。 | 出現時為translate接口設置的值到默認值0,消失時為默認值0到translate接口設置的值。 |
rotate | 通過設置組件旋轉創建轉場效果。 | 出現時為rotate接口設置的值到默認值0,消失時為默認值0到rotate接口設置的值。 |
opacity | 通過設置透明度參數創建轉場效果。 | 出現時為opacity設置的值到默認透明度1,消失時為默認透明度1到opacity設置的值。 |
move | 通過TransitionEdge創建從窗口哪條邊緣出來的效果。 | 出現時從TransitionEdge方向滑入,消失時滑出到TransitionEdge方向。 |
asymmetric | 通過此方法組合非對稱的出現消失轉場效果。 - appear:出現轉場的效果。 - disappear:消失轉場的效果。 | 出現時采用appear設置的TransitionEffect出現效果,消失時采用disappear設置的TransitionEffect消失效果。 |
combine | 組合其他TransitionEffect。 | 組合其他TransitionEffect,一起生效。 |
animation | 定義轉場效果的動畫參數: - 如果不定義會跟隨animateTo的動畫參數。 - 不支持通過控件的animation接口配置動畫參數。 - TransitionEffect中animation的onFinish不生效。 | 調用順序時從上往下,上面TransitionEffect的animation也會作用到下面TransitionEffect。 |
代碼示例
@Entry
@Component
@Preview
struct AnimPage {@State buttonScale: number = 1;@State buttonWidth: number = 100;@State showNewBtn: boolean = true// 創建默認透明度轉場效果,并指定了springMotion(0.6, 0.8)曲線private opacityEffect: TransitionEffect = TransitionEffect.OPACITY.animation({ curve: curves.springMotion(0.6, 0.8) })// 創建默認平移轉場效果, 左進右出private slideEffect: TransitionEffect = TransitionEffect.SLIDE.animation({ curve: curves.springMotion(0.6, 0.8) })private customEffect: TransitionEffect =// 創建默認透明度轉場效果,并指定了springMotion(0.6, 0.8)曲線TransitionEffect.OPACITY.animation({ curve: curves.springMotion(0.6, 0.8) })// 通過combine方法,這里的動畫參數會跟隨上面的TransitionEffect,也就是springMotion(0.6, 0.8).combine(TransitionEffect.scale({ x: 0, y: 0 }))// 添加旋轉轉場效果,這里的動畫參數會跟隨上面帶animation的TransitionEffect,也就是springMotion(0.6, 0.8).combine(TransitionEffect.rotate({ angle: 90 }))// 添加平移轉場效果,這里的動畫參數使用指定的springMotion().combine(TransitionEffect.translate({ y: 150 }).animation({ curve: curves.springMotion() }))// 添加move轉場效果,這里的動畫參數會跟隨上面的TransitionEffect,也就是springMotion().combine(TransitionEffect.move(TransitionEdge.END))build() {Column({ space: 20 }) {Button("開始動畫").onClick(() => {this.buttonScale = 1.5 / this.buttonScalethis.buttonWidth = 300 - this.buttonWidththis.showNewBtn = !this.showNewBtn}).width(this.buttonWidth).scale({ x: this.buttonScale, y: this.buttonScale }).animation({ curve: curves.springMotion() })if (this.showNewBtn) {Button("透明顯隱(默認)").transition(this.opacityEffect)}if (this.showNewBtn) {Button("左進右出").transition(this.slideEffect)}if (this.showNewBtn) {Button("自定義").transition(this.customEffect)}}.width('100%')}
}
這段代碼實現了一個包含按鈕動畫效果的界面。主要功能如下:
定義了按鈕的縮放、寬度和顯示狀態。
創建了三種動畫效果:透明度轉場、平移轉場和自定義組合轉場。
點擊“開始動畫”按鈕時,切換按鈕的縮放和寬度,并切換新按鈕的顯示狀態。
根據顯示狀態,動態展示三個帶有不同動畫效果的按鈕。
運行效果:
通過以上對鴻蒙動畫體系的介紹,特別是對屬性動畫和轉場動畫代碼示例的實操,相信開發者們對鴻蒙動畫開發有了更清晰的認識和更深入的理解。在實際開發中,充分利用這些動畫特性,將為鴻蒙應用增添無限魅力,提升用戶體驗到新的高度。
#ArkTS UI