成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

HarmonyOS 屬性動畫擴展

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

想了解更多內容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區

https://harmonyos.51cto.com

簡介

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

效果演示

HarmonyOS 屬性動畫擴展-鴻蒙HarmonyOS技術社區

實現思路

1. 動畫分類

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

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

2. 動畫操作

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

  • 開始動畫
  • 暫停動畫
  • 取消動畫
  • 結束動畫
  • 反轉動畫
  • 設置動畫起始值
  • 設置動畫延時
  • 設置動畫執行時長
  • 設置動畫插值器
  • 設置動畫狀態監聽
  • 設置動畫進度監聽
  • 設置動畫執行次數
  • 設置動畫重復模式
  • 設置組件動畫屬性值

3. 代碼實現

3.1 視圖動畫的實現

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

  1. public class ValueAnimator { 
  2.     private AnimatorValue innerAnimator; 
  3.  
  4.     // 監聽動畫值的變化 
  5.     private final AnimatorValue.ValueUpdateListener valueUpdateListener = new AnimatorValue.ValueUpdateListener() { 
  6.         @Override 
  7.         public void onUpdate(AnimatorValue animatorValue, float fraction) { 
  8.             Object[] takeValues = values
  9.             // 動畫反轉運算處理 
  10.             if (takeReverseLogic && isReversing) { 
  11.                 takeValues = reverseValues; 
  12.             } 
  13.             Object animatedValue = takeValues[0]; 
  14.             // fraction為[0,1]當前時間的進度,通過計算轉換成實際的動畫值 
  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.             // 將當前進度值通知給外部調用者 
  28.             if (updateListeners != null) { 
  29.                 notifyOuterListener(animatorValue, fraction, animatedValue); 
  30.             } 
  31.             // 如果是組件動畫,將動畫值轉換為視圖組件的屬性值變化 
  32.             if (targetHolder != null && targetHolder.get() != null) { 
  33.                 updateComponentProperty((Float) animatedValue); 
  34.             } 
  35.         } 
  36.     }; 
  37.  
  38.     // 動畫值轉換為視圖組件的屬性變化 
  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:// 中心旋轉 
  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 反向循環動畫的實現

要執行反向循環動畫,我們需要監聽循環動畫的每次循環節點,然后在下一次動畫執行開始把動畫的起始值反置。

  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.   // 設置起始值時,除了正向動畫起始值,同時構建一份反向起始值 
  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.   // 監聽動畫循環點 
  14.   private final Animator.LoopedListener loopedListener = new Animator.LoopedListener() { 
  15.       @Override 
  16.       public void onRepeat(Animator animator) { 
  17.           // 如果循環模式設置為反向,下次執行動畫則反向執行 
  18.           // 例如當前是[0,1],動畫結束后就會從[1,0]開始執行,再下次又從[0,1],如此循環... 
  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.   // 監聽動畫值的變化 
  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.               // 根據循環模式讀取正向還是反向起始值 
  37.               takeValues = reverseValues; 
  38.           } 
  39.           ... 
  40.   }; 
  41.  
  42.   // 反向執行動畫 
  43.   public void reverse() { 
  44.       takeReverseLogic = !takeReverseLogic; 
  45.       isReversing = !isReversing; 
  46.       // 先停止當前動畫,然后再反向執行動畫 
  47.       if (innerAnimator.isRunning()) { 
  48.           innerAnimator.end(); 
  49.       } 
  50.       innerAnimator.start(); 
  51.   } 

3.3 動畫操作的實現

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

  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. ... 

總結

通過我們對原生AnimatorValue的擴展,我們實現了實際開發中大部分應用場景,讓實際開發動畫的效率可以大大提升。總結一下幾點核心的擴展原理:

  • 視圖組件動畫實現:監聽原生動畫值進行倍率轉換,再設置給組件通用屬性
  • 反向/循環動畫實現:監聽循環動畫的循環節點,反向賦值下一次動畫的起始值

想了解更多內容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區

https://harmonyos.51cto.com

 

責任編輯:jianghua 來源: 鴻蒙社區
相關推薦

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動畫

2013-12-18 09:36:28

Radius擴展屬性IPv6

2023-09-15 13:31:00

Linuxattr

2015-05-07 14:45:40

Cocos 插件

2021-11-29 06:57:50

App使用屬性

2009-12-01 09:30:34

ASP.NET MVC

2021-06-04 10:52:39

Chrome瀏覽器Google

2011-08-01 15:20:51

SQL Server索引

2023-04-23 09:01:43

CSS動畫合成

2023-04-24 09:23:31

CSS動畫合成

2021-02-21 08:12:24

SVG線條動畫Web動畫

2024-07-01 12:13:44

2023-01-06 08:06:52

Groovy類型擴展

2022-03-29 11:28:24

HarmonyOS動畫css

2022-08-29 17:39:53

應用開發css動畫

2012-12-24 13:38:01

iOSUIView
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: www.日日夜夜 | 久久午夜电影 | 欧美a区 | 日韩精品一区二区三区在线播放 | 国产高清在线观看 | www.中文字幕.com | 伊人影院在线观看 | 高清黄色 | 黄色一级电影免费观看 | 青娱乐国产 | 欧美激情综合 | 天堂影院av | 亚洲午夜视频 | 精品一区二区三区在线观看 | av国产精品 | 久久久精品一区 | 国产黄色一级片 | 91精品国产91久久久久久最新 | 亚洲精品电影 | 欧美成人一区二区 | 国产精品美女久久久久 | 国产小网站 | 成av人电影在线 | 新超碰97 | 一区二区三区在线看 | 日本午夜网 | a级毛片国产 | 国产高清精品在线 | 久久一区二区三区四区五区 | 欧美成人精品 | 一区二区不卡 | 日本大片在线播放 | 国产精品一区三区 | 久久九七| 久久精品1 | xxxxx免费视频| 成人在线免费 | 亚洲一区二区三区免费在线观看 | 黄色片在线看 | 欧美一区二区三区小说 | 久久精品91久久久久久再现 |