W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
顯式動畫(animateTo)和屬性動畫(animation)是ArkUI提供的最基礎(chǔ)和常用的動畫功能。在布局屬性(如尺寸屬性、位置屬性)發(fā)生變化時,可以通過屬性動畫或顯式動畫,按照動畫參數(shù)過渡到新的布局參數(shù)狀態(tài)。
動畫類型 | 特點 |
---|---|
顯式動畫 | 閉包內(nèi)的變化均會觸發(fā)動畫,包括由數(shù)據(jù)變化引起的組件的增刪、組件屬性的變化等,可以做較為復(fù)雜的動畫。 |
屬性動畫 | 動畫設(shè)置簡單,屬性變化時自動觸發(fā)動畫。 |
顯式動畫的接口為:
- animateTo(value: AnimateParam, event: () => void): void
第一個參數(shù)指定動畫參數(shù),第二個參數(shù)為動畫的閉包函數(shù)。
以下是使用顯式動畫產(chǎn)生布局更新動畫的示例。示例中,當Column組件的alignItems屬性改變后,其子組件的布局位置結(jié)果發(fā)生變化。只要該屬性是在animateTo的閉包函數(shù)中修改的,那么由其引起的所有變化都會按照animateTo的動畫參數(shù)執(zhí)行動畫過渡到終點值。
- @Entry
- @Component
- struct LayoutChange {
- // 用于控制Column的alignItems屬性
- @State itemAlign: HorizontalAlign = HorizontalAlign.Start;
- allAlign: HorizontalAlign[] = [HorizontalAlign.Start, HorizontalAlign.Center, HorizontalAlign.End];
- alignIndex: number = 0;
- build() {
- Column() {
- Column({ space: 10 }) {
- Button("1").width(100).height(50)
- Button("2").width(100).height(50)
- Button("3").width(100).height(50)
- }
- .margin(20)
- .alignItems(this.itemAlign)
- .borderWidth(2)
- .width("90%")
- .height(200)
- Button("click").onClick(() => {
- // 動畫時長為1000ms,曲線為EaseInOut
- animateTo({ duration: 1000, curve: Curve.EaseInOut }, () => {
- this.alignIndex = (this.alignIndex + 1) % this.allAlign.length;
- // 在閉包函數(shù)中修改this.itemAlign參數(shù),使Column容器內(nèi)部孩子的布局方式變化,使用動畫過渡到新位置
- this.itemAlign = this.allAlign[this.alignIndex];
- });
- })
- }
- .width("100%")
- .height("100%")
- }
- }
除直接改變布局方式外,也可直接修改組件的寬、高、位置。
- @Entry
- @Component
- struct LayoutChange2 {
- @State myWidth: number = 100;
- @State myHeight: number = 50;
- // 標志位,true和false分別對應(yīng)一組myWidth、myHeight值
- @State flag: boolean = false;
- build() {
- Column({ space: 10 }) {
- Button("text")
- .type(ButtonType.Normal)
- .width(this.myWidth)
- .height(this.myHeight)
- .margin(20)
- Button("area: click me")
- .fontSize(12)
- .margin(20)
- .onClick(() => {
- animateTo({ duration: 1000, curve: Curve.Ease }, () => {
- // 動畫閉包中根據(jù)標志位改變控制第一個Button寬高的狀態(tài)變量,使第一個Button做寬高動畫
- if (this.flag) {
- this.myWidth = 100;
- this.myHeight = 50;
- } else {
- this.myWidth = 200;
- this.myHeight = 100;
- }
- this.flag = !this.flag;
- });
- })
- }
- .width("100%")
- .height("100%")
- }
- }
在第二個Button的點擊事件中,使用animateTo函數(shù),在閉包中修改this.myWidth和this.myHeight狀態(tài)變量,而這兩個狀態(tài)變量分別為第一個Button的寬、高屬性值,所以第一個Button做了寬高動畫。效果如下圖。
與此同時,第二個Button也產(chǎn)生了一個位置動畫。這是由于第一個Button的寬高變化后,引起了Column內(nèi)部其他組件的布局結(jié)果也發(fā)生了變化,第二個Button的布局發(fā)生變化也是由于閉包內(nèi)改變第一個Button的寬高造成的。
如果不希望第二個Button有動畫效果,有兩種方式可以實現(xiàn)。一種是給做第一個Button外面再加一個容器,使其動畫前后的大小都在容器的范圍內(nèi),這樣第二個Button的位置不會被第一個Button的位置所影響。修改后的核心代碼如下。
- Column({ space: 10 }) {
- Column() {
- // Button放在足夠大的容器內(nèi),使其不影響更外層的組件位置
- Button("text")
- .type(ButtonType.Normal)
- .width(this.myWidth)
- .height(this.myHeight)
- }
- .margin(20)
- .width(200)
- .height(100)
- Button("area: click me")
- .fontSize(12)
- .onClick(() => {
- animateTo({ duration: 1000, curve: Curve.Ease }, () => {
- // 動畫閉包中根據(jù)標志位改變控制第一個Button寬高的狀態(tài)變量,使第一個Button做寬高動畫
- if (this.flag) {
- this.myWidth = 100;
- this.myHeight = 50;
- } else {
- this.myWidth = 200;
- this.myHeight = 100;
- }
- this.flag = !this.flag;
- });
- })
- }
- .width("100%")
- .height("100%")
另一種方式是給第二個Button添加布局約束,如position的位置約束,使其位置不被第一個Button的寬高影響。核心代碼如下:
- Column({ space: 10 }) {
- Button("text")
- .type(ButtonType.Normal)
- .width(this.myWidth)
- .height(this.myHeight)
- .margin(20)
- Button("area: click me")
- .fontSize(12)
- // 配置position屬性固定,使自己的布局位置不被第一個Button的寬高影響
- .position({ x: "30%", y: 200 })
- .onClick(() => {
- animateTo({ duration: 1000, curve: Curve.Ease }, () => {
- // 動畫閉包中根據(jù)標志位改變控制第一個Button寬高的狀態(tài)變量,使第一個Button做寬高動畫
- if (this.flag) {
- this.myWidth = 100;
- this.myHeight = 50;
- } else {
- this.myWidth = 200;
- this.myHeight = 100;
- }
- this.flag = !this.flag;
- });
- })
- }
- .width("100%")
- .height("100%")
顯式動畫把要執(zhí)行動畫的屬性的修改放在閉包函數(shù)中觸發(fā)動畫,而屬性動畫則無需使用閉包,把animation屬性加在要做屬性動畫的組件的屬性后即可。
屬性動畫的接口為:
- animation(value: AnimateParam)
其入?yún)閯赢媴?shù)。想要組件隨某個屬性值的變化而產(chǎn)生動畫,此屬性需要加在animation屬性之前。有的屬性變化不希望通過animation產(chǎn)生屬性動畫,可以放在animation之后。上面顯式動畫的示例很容易改為用屬性動畫實現(xiàn)。例如:
- @Entry
- @Component
- struct LayoutChange2 {
- @State myWidth: number = 100;
- @State myHeight: number = 50;
- @State flag: boolean = false;
- @State myColor: Color = Color.Blue;
- build() {
- Column({ space: 10 }) {
- Button("text")
- .type(ButtonType.Normal)
- .width(this.myWidth)
- .height(this.myHeight)
- // animation只對其上面的type、width、height屬性生效,時長為1000ms,曲線為Ease
- .animation({ duration: 1000, curve: Curve.Ease })
- // animation對下面的backgroundColor、margin屬性不生效
- .backgroundColor(this.myColor)
- .margin(20)
- Button("area: click me")
- .fontSize(12)
- .onClick(() => {
- // 改變屬性值,配置了屬性動畫的屬性會進行動畫過渡
- if (this.flag) {
- this.myWidth = 100;
- this.myHeight = 50;
- this.myColor = Color.Blue;
- } else {
- this.myWidth = 200;
- this.myHeight = 100;
- this.myColor = Color.Pink;
- }
- this.flag = !this.flag;
- })
- }
- }
- }
上述示例中,第一個button上的animation屬性,只對寫在animation之前的type、width、height屬性生效,而對寫在animation之后的backgroundColor、margin屬性無效。運行結(jié)果是width、height屬性會按照animation的動畫參數(shù)執(zhí)行動畫,而backgroundColor會直接跳變,不會產(chǎn)生動畫。效果如下圖:
1. 使用屬性動畫時,會按照指定的屬性動畫參數(shù)執(zhí)行動畫。每個組件可為自己的屬性配置不同參數(shù)的屬性動畫。
2. 顯式動畫會對動畫閉包前后造成的所有界面差異執(zhí)行動畫,且使用同一動畫參數(shù),適用于統(tǒng)一執(zhí)行的場景。此外,顯式動畫也可以用于一些非屬性變量造成的動畫,如if/else的條件,F(xiàn)orEach使用的數(shù)組元素的刪減。
3. 如果一個屬性配置了屬性動畫,且在顯式動畫閉包中改變該屬性值,屬性動畫優(yōu)先生效,會使用屬性動畫的動畫參數(shù)。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: