自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

HarmonyOS 屬性動畫擴展

系統(tǒng)
在日常開發(fā)中,我們經(jīng)常需要基于這個類進行擴展編寫,去適應(yīng)真實場景。因此,通過收集常用的場景,整理出一個屬性動畫的擴展類ValueAnimator。

想了解更多內(nèi)容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

簡介

HarmonyOS 提供了AnimatorValue來執(zhí)行屬性動畫,但是其方法數(shù)很少,并且屬性值范圍局限于[0,1],也不直接支持動畫反轉(zhuǎn)等一些常用的操作。在日常開發(fā)中,我們經(jīng)常需要基于這個類進行擴展編寫,去適應(yīng)真實場景。因此,通過收集常用的場景,整理出一個屬性動畫的擴展類ValueAnimator。

效果演示

HarmonyOS 屬性動畫擴展-鴻蒙HarmonyOS技術(shù)社區(qū)

實現(xiàn)思路

1. 動畫分類

實際開發(fā)過程,我們大部分的動畫都是作用于視圖組件。任何復(fù)雜的動畫,通過逐幀分解,最終都可以歸納為如下幾種基礎(chǔ)動畫的組合:

  • X,Y軸縮放動畫
  • X,Y軸平移動畫
  • 透明度動畫
  • 旋轉(zhuǎn)角度動畫
  • 組件寬高尺寸動畫

2. 動畫操作

對于動畫的操作,我們可以歸納出以下這些動作:

  • 開始動畫
  • 暫停動畫
  • 取消動畫
  • 結(jié)束動畫
  • 反轉(zhuǎn)動畫
  • 設(shè)置動畫起始值
  • 設(shè)置動畫延時
  • 設(shè)置動畫執(zhí)行時長
  • 設(shè)置動畫插值器
  • 設(shè)置動畫狀態(tài)監(jiān)聽
  • 設(shè)置動畫進度監(jiān)聽
  • 設(shè)置動畫執(zhí)行次數(shù)
  • 設(shè)置動畫重復(fù)模式
  • 設(shè)置組件動畫屬性值

3. 代碼實現(xiàn)

3.1 視圖動畫的實現(xiàn)

系統(tǒng)原生提供的AnimatorValue為我們提供了[0,1]的動畫范圍。因此最簡單的實現(xiàn)方式是定義一個ValueAnimator,內(nèi)部包含一個系統(tǒng)的AnimatorValue來計算[0,1]的進度值,通過自己的邏輯轉(zhuǎn)換為我們期望的動畫值。

  1. public class ValueAnimator { 
  2.     private AnimatorValue innerAnimator; 
  3.  
  4.     // 監(jiān)聽動畫值的變化 
  5.     private final AnimatorValue.ValueUpdateListener valueUpdateListener = new AnimatorValue.ValueUpdateListener() { 
  6.         @Override 
  7.         public void onUpdate(AnimatorValue animatorValue, float fraction) { 
  8.             Object[] takeValues = values
  9.             // 動畫反轉(zhuǎn)運算處理 
  10.             if (takeReverseLogic && isReversing) { 
  11.                 takeValues = reverseValues; 
  12.             } 
  13.             Object animatedValue = takeValues[0]; 
  14.             // fraction為[0,1]當(dāng)前時間的進度,通過計算轉(zhuǎn)換成實際的動畫值 
  15.             if (animatedValue != null) { 
  16.                 if (animatedValue instanceof Integer) { 
  17.                     int start = (int) takeValues[0]; 
  18.                     int end = (int) takeValues[1]; 
  19.                     animatedValue = start + (int) (fraction * (end - start)); 
  20.                 } else { 
  21.                     float start = (float) takeValues[0]; 
  22.                     float end = (float) takeValues[1]; 
  23.                     animatedValue = start + fraction * (end - start); 
  24.                 } 
  25.             } 
  26.             currentAnimatedValue = animatedValue; 
  27.             // 將當(dāng)前進度值通知給外部調(diào)用者 
  28.             if (updateListeners != null) { 
  29.                 notifyOuterListener(animatorValue, fraction, animatedValue); 
  30.             } 
  31.             // 如果是組件動畫,將動畫值轉(zhuǎn)換為視圖組件的屬性值變化 
  32.             if (targetHolder != null && targetHolder.get() != null) { 
  33.                 updateComponentProperty((Float) animatedValue); 
  34.             } 
  35.         } 
  36.     }; 
  37.  
  38.     // 動畫值轉(zhuǎn)換為視圖組件的屬性變化 
  39.     private void updateComponentProperty(Float currentValue) { 
  40.         Component component = targetHolder.get(); 
  41.         for (Property property : targetProperties) { 
  42.             switch (property) { 
  43.                 case SCALE_X:// 縮放x 
  44.                     component.setScaleX(currentValue); 
  45.                     break; 
  46.                 case SCALE_Y:// 縮放y 
  47.                     component.setScaleY(currentValue); 
  48.                     break; 
  49.                 case TRANSLATION_X:// 平移x 
  50.                     component.setTranslationX(currentValue); 
  51.                     break; 
  52.                 case TRANSLATION_Y:// 平移y 
  53.                     component.setTranslationY(currentValue); 
  54.                     break; 
  55.                 case ALPHA:// 透明度 
  56.                     component.setAlpha(currentValue); 
  57.                     break; 
  58.                 case ROTATION:// 中心旋轉(zhuǎn) 
  59.                     component.setRotation(currentValue); 
  60.                     break; 
  61.                 case WIDTH:// 尺寸寬 
  62.                     float width = currentValue; 
  63.                     component.setWidth((int) width); 
  64.                     break; 
  65.                 case HEIGHT:// 尺寸高 
  66.                     float height = currentValue; 
  67.                     component.setHeight((int) height); 
  68.                     break; 
  69.                 default
  70.                     break; 
  71.             } 
  72.         } 
  73.     } 

3.2 反向循環(huán)動畫的實現(xiàn)

要執(zhí)行反向循環(huán)動畫,我們需要監(jiān)聽循環(huán)動畫的每次循環(huán)節(jié)點,然后在下一次動畫執(zhí)行開始把動畫的起始值反置。

  1. private static final int MAX_SIZE = 2; 
  2.   private final Object[] values = new Object[MAX_SIZE];// 正向動畫起始值 
  3.   private final Object[] reverseValues = new Object[MAX_SIZE];// 反向動畫起始值 
  4.  
  5.   // 設(shè)置起始值時,除了正向動畫起始值,同時構(gòu)建一份反向起始值 
  6.   public void setFloatValues(float start, float end) { 
  7.       values[0] = start; 
  8.       values[1] = end
  9.       reverseValues[0] = end
  10.       reverseValues[1] = start; 
  11.   } 
  12.  
  13.   // 監(jiān)聽動畫循環(huán)點 
  14.   private final Animator.LoopedListener loopedListener = new Animator.LoopedListener() { 
  15.       @Override 
  16.       public void onRepeat(Animator animator) { 
  17.           // 如果循環(huán)模式設(shè)置為反向,下次執(zhí)行動畫則反向執(zhí)行 
  18.           // 例如當(dāng)前是[0,1],動畫結(jié)束后就會從[1,0]開始執(zhí)行,再下次又從[0,1],如此循環(huán)... 
  19.           if (takeReverseLogic) { 
  20.               isReversing = !isReversing; 
  21.           } 
  22.           if (listeners != null) { 
  23.               for (AnimatorListener listener : listeners) { 
  24.                   listener.onAnimationRepeat(ValueAnimator.this); 
  25.               } 
  26.           } 
  27.       } 
  28.   }; 
  29.  
  30.   // 監(jiān)聽動畫值的變化 
  31.   private final AnimatorValue.ValueUpdateListener valueUpdateListener = new AnimatorValue.ValueUpdateListener() { 
  32.       @Override 
  33.       public void onUpdate(AnimatorValue animatorValue, float fraction) { 
  34.           Object[] takeValues = values
  35.           if (takeReverseLogic && isReversing) { 
  36.               // 根據(jù)循環(huán)模式讀取正向還是反向起始值 
  37.               takeValues = reverseValues; 
  38.           } 
  39.           ... 
  40.   }; 
  41.  
  42.   // 反向執(zhí)行動畫 
  43.   public void reverse() { 
  44.       takeReverseLogic = !takeReverseLogic; 
  45.       isReversing = !isReversing; 
  46.       // 先停止當(dāng)前動畫,然后再反向執(zhí)行動畫 
  47.       if (innerAnimator.isRunning()) { 
  48.           innerAnimator.end(); 
  49.       } 
  50.       innerAnimator.start(); 
  51.   } 

3.3 動畫操作的實現(xiàn)

因為我們核心的動畫值計算是基于原生的ValueAnimator,因此我們基本的動畫操作也是對其執(zhí)行:

  1. private AnimatorValue innerAnimator; 
  2.  
  3. // 開始動畫 
  4. public void start() { 
  5.     if (innerAnimator.getLoopedCount() == AnimatorValue.INFINITE) { 
  6.         if (repeatMode == RepeatMode.REVERSE) { 
  7.             takeReverseLogic = true
  8.         } 
  9.     } 
  10.     // 對innerAnimator操作 
  11.     innerAnimator.start(); 
  12. }     
  13.  
  14. // 停止動畫 
  15. public void stop() { 
  16.     // 對innerAnimator操作 
  17.     innerAnimator.stop(); 
  18.  
  19. // 取消動畫 
  20. public void cancel() { 
  21.     // 對innerAnimator操作 
  22.     innerAnimator.cancel(); 
  23.  
  24. // 其他操作方法聲明 
  25. ... 

總結(jié)

通過我們對原生AnimatorValue的擴展,我們實現(xiàn)了實際開發(fā)中大部分應(yīng)用場景,讓實際開發(fā)動畫的效率可以大大提升??偨Y(jié)一下幾點核心的擴展原理:

  • 視圖組件動畫實現(xiàn):監(jiān)聽原生動畫值進行倍率轉(zhuǎn)換,再設(shè)置給組件通用屬性
  • 反向/循環(huán)動畫實現(xiàn):監(jiān)聽循環(huán)動畫的循環(huán)節(jié)點,反向賦值下一次動畫的起始值

想了解更多內(nèi)容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

 

責(zé)任編輯:jianghua 來源: 鴻蒙社區(qū)
相關(guān)推薦

2021-12-01 18:36:35

屬性

2009-12-24 17:10:42

WPF動畫類

2009-12-01 10:08:23

WF4屬性

2011-08-12 11:31:46

iPhoneUIView動畫

2011-08-09 17:16:56

CoreAnimati動畫

2023-09-15 13:31:00

Linuxattr

2015-05-07 14:45:40

Cocos 插件

2021-11-29 06:57:50

App使用屬性

2013-12-18 09:36:28

Radius擴展屬性IPv6

2021-06-04 10:52:39

Chrome瀏覽器Google

2009-12-01 09:30:34

ASP.NET MVC

2011-08-01 15:20:51

SQL Server索引

2023-04-23 09:01:43

CSS動畫合成

2023-04-24 09:23:31

CSS動畫合成

2012-12-24 13:38:01

iOSUIView

2021-02-21 08:12:24

SVG線條動畫Web動畫

2023-01-06 08:06:52

Groovy類型擴展

2024-07-01 12:13:44

2022-08-29 17:39:53

應(yīng)用開發(fā)css動畫

2022-03-29 11:28:24

HarmonyOS動畫css
點贊
收藏

51CTO技術(shù)棧公眾號