Android動畫自定義解析

原理分析:

首先說Animation(android.view.animation.Animation)對象,無論是用純java代碼構建Animation對象,還是通過xml文件定義Animation,其實最終的結果都是
Animation a = new AlphaAnimation();Animation s = new ScaleAnimation();Animation r = new RotateAnimation();Animation t = new TranslateAnimation();
分別是透明度,縮放,旋轉,位移四種動畫效果。

而我們使用的時候,一般是用這樣的形式:
這裏寫圖片描述

那麼就來看看View中的startAnimation()方法:
這裏寫圖片描述

先是調用View.setAnimation(Animation)方法給自己設置一個Animation對象,這個對象是View類中的一個名爲mCurrentAnimation的成員變量:
這裏寫圖片描述

然後它調用invalidate()來重繪自己。我想,既然setAnimation()了,那麼它要用的時候,肯定要getAnimation(),找到這個方法在哪裏調用就好了。於是通過搜索,在View.draw(Canvas, ViewGroup, long)方法中發現了它的調用,代碼片段如下:
這裏寫圖片描述

其中調用了View.drawAnimation()方法:
這裏寫圖片描述

其中調用了Animation.getTransformation()方法:
這裏寫圖片描述

該方法先將參數currentTime處理成一個float表示當前動畫進度,比如說,一個2000ms的動畫,已經執行了1000ms了,那麼進度就是0.5或者說50%。然後將進度值傳入插值器(Interpolator)得到新的進度值,前者是均勻的,隨着時間是一個直線的線性關係,而通過插值器計算後得到的是一個曲線的關係。然後將新的進度值和Transformation對象傳入applyTranformation()方法中:

Animation的applyTransformation()方法是空實現:
這裏寫圖片描述

而具體實現它的是Animation的四個子類,而該方法正是真正的處理動畫變化的過程。分別看下四個子類的applyTransformation()的實現:
這裏寫圖片描述

其中一個代碼如下:
這裏寫圖片描述

可見applyTransformation()方法就是動畫具體的實現,系統會以一個比較高的頻率來調用這個方法,一般情況下60FPS,是一個非常流暢的畫面了,也就是16ms,爲了驗證這一點,我在applyTransformation方法中加入計算時間間隔並打印的代碼進行驗證,代碼如下:

自定義:

這裏寫圖片描述

調用:

這裏寫圖片描述

打印:

封裝一個InterpolatedTime(float time)函數,在applyTransformation調用:
這裏寫圖片描述

Log:

這裏寫圖片描述

右側是“手動”計算出來的時間差,有一定的波動,但大致上是16-17ms的樣子,左側是日誌打印的時間,時間非常規則的相差20ms。

總結:

於是,根據以上的結果,可以得出以下內容:
1.首先證明了一點,Animation.applyTransformation()方法,是動畫具體的調用方法,我們可以覆寫這個方法,快速的製作自己的動畫。

2.另一點,爲什麼是16ms左右調用這個方法呢?是誰來控制這個頻率的?

關於第二點,要分析:Choreographer!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章