1. 程式人生 > >Android屬性動畫完全解析,Interpolator和ViewPropertyAnimator的用法

Android屬性動畫完全解析,Interpolator和ViewPropertyAnimator的用法

大家好,歡迎繼續回到Android屬性動畫完全解析。在上一篇文章當中我們學習了屬性動畫的一些進階技巧,包括ValueAnimator和ObjectAnimator的高階用法,那麼除了這些之外,當然還有一些其它的高階技巧在等著我們學習,因此本篇文章就對整個屬性動畫完全解析系列收個尾,來學習一下剩下的非常重要的高階技巧。

Interpolator的用法

Interpolator這個東西很難進行翻譯,直譯過來的話是補間器的意思,它的主要作用是可以控制動畫的變化速率,比如去實現一種非線性運動的動畫效果。那麼什麼叫做非線性運動的動畫效果呢?就是說動畫改變的速率不是一成不變的,像加速運動以及減速運動都屬於非線性運動。

不過Interpolator並不是屬性動畫中新增的技術,實際上從Android 1.0版本開始就一直存在Interpolator介面了,而之前的補間動畫當然也是支援這個功能的。只不過在屬性動畫中新增了一個TimeInterpolator介面,這個介面是用於相容之前的Interpolator的,這使得所有過去的Interpolator實現類都可以直接拿過來放到屬性動畫當中使用,那麼我們來看一下現在TimeInterpolator介面的所有實現類,如下圖所示:


可以看到,TimeInterpolator介面已經有非常多的實現類了,這些都是Android系統內建好的並且我們可以直接使用的Interpolator。每個Interpolator都有它各自的實現效果,比如說AccelerateInterpolator就是一個加速運動的Interpolator,而DecelerateInterpolator就是一個減速運動的Interpolator。

我覺得細心的朋友應該早已經發現了,在前面兩篇文章當中我們所學到的所有屬性動畫,其實都不是在進行一種執行緒運動。比如說在“上”篇文章中使用ValueAnimator所列印的值如下所示:


可以看到,一開始的值變化速度明顯比較慢,僅0.0開頭的就列印了4次,之後開始加速,最後階段又開始減速,因此我們可以很明顯地看出這一個先加速後減速的Interpolator。

那麼再來看一下在“中”篇文章中完成的小球移動加變色的功能,如下圖所示:


從上圖中我們明顯可以看出,小球一開始運動速度比較慢,然後逐漸加速,中間的部分運動速度就比較快,接下來開始減速,最後緩緩停住。另外顏色變化也是這種規律,一開始顏色變化的比較慢,中間顏色變化的很快,最後階段顏色變化的又比較慢。

從以上幾點我們就可以總結出一個結論了,使用屬性動畫時,系統預設的Interpolator其實就是一個先加速後減速的Interpolator,對應的實現類就是AccelerateDecelerateInterpolator。

當然,我們也可以很輕鬆地修改這一預設屬性,將它替換成任意一個系統內建好的Interpolator。就拿“中”篇文章中的程式碼來舉例吧,MyAnimView中的startAnimation()方法是開啟動畫效果的入口,這裡我們對Point物件的座標稍做一下修改,讓它變成一種垂直掉落的效果,程式碼如下所示:

  1. privatevoid startAnimation() {  
  2.     Point startPoint = new Point(getWidth() / 2, RADIUS);  
  3.     Point endPoint = new Point(getWidth() / 2, getHeight() - RADIUS);  
  4.     ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);  
  5.     anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {  
  6.         @Override
  7.         publicvoid onAnimationUpdate(ValueAnimator animation) {  
  8.             currentPoint = (Point) animation.getAnimatedValue();  
  9.             invalidate();  
  10.         }  
  11.     });  
  12.     anim.setDuration(2000);  
  13.     anim.start();  
  14. }  
這裡主要是對Point建構函式中的座標值進行了一下改動,那麼現在小球運動的動畫效果應該是從螢幕正中央的頂部掉落到底部。但是現在預設情況下小球的下降速度肯定是先加速後減速的,這不符合物理的常識規律,如果把小球視為一個自由落體的話,那麼下降的速度應該是越來越快的。我們怎樣才能改變這一預設行為呢?其實很簡單,呼叫Animator的setInterpolator()方法就可以了,這個方法要求傳入一個實現TimeInterpolator介面的例項,那麼比如說我們想要實現小球下降越來越快的效果,就可以使用AccelerateInterpolator,程式碼如下所示:
  1. privatevoid startAnimation() {  
  2.     Point startPoint = new Point(getWidth() / 2, RADIUS);  
  3.     Point endPoint = new Point(getWidth() / 2, getHeight() - RADIUS);  
  4.     ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);  
  5.     anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {  
  6.         @Override
  7.         publicvoid onAnimationUpdate(ValueAnimator animation) {  
  8.             currentPoint = (Point) animation.getAnimatedValue();  
  9.             invalidate();  
  10.         }  
  11.     });  
  12.     anim.setInterpolator(new AccelerateInterpolator(2f));  
  13.     anim.setDuration(2500);  
  14.     anim.start();  
  15. }  

程式碼很簡單,這裡呼叫了setInterpolator()方法,然後傳入了一個AccelerateInterpolator的例項,注意AccelerateInterpolator的構建函式可以接收一個float型別的引數,這個引數是用於控制加速度的。現在執行一下程式碼,效果如下圖所示:


OK,效果非常明顯,說明我們已經成功替換掉了預設的Interpolator,AccelerateInterpolator確實是生效了。但是現在的動畫效果看上去仍然是怪怪的,因為一個小球從很高的地方掉落到地面上直接就靜止了,這也是不符合物理規律的,小球撞擊到地面之後應該要反彈起來,然後再次落下,接著再反彈起來,又再次落下,以此反覆,最後靜止。這個功能我們當然可以自己去寫,只不過比較複雜,所幸的是,Android系統中已經提供好了這樣一種Interpolator,我們只需要簡單地替換一下就可以完成上面的描述的效果,程式碼如下所示:

  1. privatevoid startAnimation() {  
  2.     Point startPoint = new Point(getWidth() / 2, RADIUS);  
  3.     Point endPoint = new Point(getWidth() / 2, getHeight() - RADIUS);  
  4.     ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);  
  5.     anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {  
  6.         @Override
  7.         publicvoid onAnimationUpdate(ValueAnimator animation) {  
  8.             currentPoint = (Point) animation.getAnimatedValue();  
  9.             invalidate();  
  10.         }  
  11.     });  
  12.     anim.setInterpolator(new BounceInterpolator());  
  13.     anim.setDuration(3000);  
  14.     anim.start();  
  15. }  
可以看到,我們只是將設定的Interpolator換成了BounceInterpolator的例項,而BounceInterpolator就是一種可以模擬物理規律,實現反覆彈起效果的Interpolator。另外還將整體的動畫時間稍微延長了一點,因為小球反覆彈起需要比之前更長的時間。現在重新執行一下程式碼,效果如下圖所示:


OK!效果還是非常不錯的。那麼這裡我們只是選了幾個系統實現好的Interpolator,由於內建Interpolator非常多,就不一一進行講解了,大家可以自己去使用一下其它的幾種Interpolator來看一看效果。

但是,只會用一下系統提供好的Interpolator,我們顯然對自己的要求就太低了,既然是學習屬性動畫的高階用法,那麼自然要將它研究透了。下面我們就來看一下Interpolator的內部實現機制是什麼樣的,並且來嘗試寫一個自定義的Interpolator。

首先看一下TimeInterpolator的介面定義,程式碼如下所示:

  1. /** 
  2.  * A time interpolator defines the rate of change of an animation. This allows animations 
  3.  * to have non-linear motion, such as acceleration and deceleration. 
  4.  */
  5. publicinterface TimeInterpolator {  
  6.     /** 
  7.      * Maps a value representing the elapsed fraction of an animation to a value that represents 
  8.      * the interpolated fraction. This interpolated value is then multiplied by the change in 
  9.      * value of an animation to derive the animated value at the current elapsed animation time. 
  10.      * 
  11.      * @param input A value between 0 and 1.0 indicating our current point 
  12.      *        in the animation where 0 represents the start and 1.0 represents 
  13.      *        the end 
  14.      * @return The interpolation value. This value can be more than 1.0 for 
  15.      *         interpolators which overshoot their targets, or less than 0 for 
  16.      *         interpolators that undershoot their targets. 
  17.      */
  18.     float getInterpolation(float input);  
  19. }  

OK,介面還是非常簡單的,只有一個getInterpolation()方法。大家有興趣可以通過註釋來對這個介面進行詳解的瞭解,這裡我就簡單解釋一下,getInterpolation()方法中接收一個input引數,這個引數的值會隨著動畫的執行而不斷變化,不過它的變化是非常有規律的,就是根據設定的動畫時長勻速增加,變化範圍是0到1。也就是說當動畫一開始的時候input的值是0,到動畫結束的時候input的值是1,而中間的值則是隨著動畫執行的時長在0到1之間變化的。

說到這個input的值,我覺得有不少朋友可能會聯想到我們在“中”篇文章中使用過的fraction值。那麼這裡的input和fraction有什麼關係或者區別呢?答案很簡單,input的值決定了fraction的值。input的值是由系統經過計算後傳入到getInterpolation()方法中的,然後我們可以自己實現getInterpolation()方法中的演算法,根據input的值來計算出一個返回值,而這個返回值就是fraction了。

因此,最簡單的情況就是input值和fraction值是相同的,這種情況由於input值是勻速增加的,因而fraction的值也是勻速增加的,所以動畫的運動情況也是勻速的。系統中內建的LinearInterpolator就是一種勻速運動的Interpolator,那麼我們來看一下它的原始碼是怎麼實現的:

  1. /** 
  2.  * An interpolator where the rate of change is constant 
  3.  */
  4. @HasNativeInterpolator
  5. publicclass LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {  
  6.     public LinearInterpolator() {  
  7.     }  
  8.     public LinearInterpolator(Context context, AttributeSet attrs) {  
  9.     }  
  10.     publicfloat getInterpolation(float input) {  
  11.         return input;  
  12.     }  
  13.     /** @hide */
  14.     @Override
  15.     publiclong createNativeInterpolator() {  
  16.         return NativeInterpolatorFactoryHelper.createLinearInterpolator();  
  17.     }  
  18. }  

這裡我們只看getInterpolation()方法,這個方法沒有任何邏輯,就是把引數中傳遞的input值直接返回了,因此fraction的值就是等於input的值的,這就是勻速運動的Interpolator的實現方式。

當然這是最簡單的一種Interpolator的實現了,我們再來看一個稍微複雜一點的。既然現在大家都知道了系統在預設情況下使用的是AccelerateDecelerateInterpolator,那我們就來看一下它的原始碼吧,如下所示:

  1. /** 
  2.  * An interpolator where the rate of change starts and ends slowly but 
  3.  * accelerates through the middle. 
  4.  *  
  5. 相關推薦

    Android屬性動畫完全解析InterpolatorViewPropertyAnimator用法

    大家好,歡迎繼續回到Android屬性動畫完全解析。在上一篇文章當中我們學習了屬性動畫的一些進階技巧,包括ValueAnimator和ObjectAnimator的高階用法,那麼除了這些之外,當然還有一些其它的高階技巧在等著我們學習,因此本篇文章就對整個屬性動畫完

    Android屬性動畫完全解析InterpolatorViewPropertyAnimator用法

                    大家好,歡迎繼續回到Android屬性動畫完全解析。在上一篇文章當中我們學習了屬性動畫的一些進階技巧,包括ValueAnimator和ObjectAnimator的高階用法,那麼除了這些之外,當然還有一些其它的高階技巧在等著我們學習,因此本篇文章就對整個屬性動畫完全解析系列收個

    Android屬性動畫完全解析(下)InterpolatorViewPropertyAnimator用法

    大家好,歡迎繼續回到Android屬性動畫完全解析。在上一篇文章當中我們學習了屬性動畫的一些進階技巧,包括ValueAnimator和ObjectAnimator的高階用法,那麼除了這些之外,當然還有一些其它的高階技巧在等著我們學習,因此本篇文章就對整個屬性動畫完全解析系列收

    Android屬性動畫完全解析ValueAnimatorObjectAnimator的高階用法

    轉載請註明出處:http://blog.csdn.net/guolin_blog/article/details/43536355 大家好,在上一篇文章當中,我們學習了Android屬性動畫的基本用法,當然也是最常用的一些用法,這些用法足以覆蓋我們平時大多情況下的動畫需求了。但是,正如上篇文章當中所

    Android屬性動畫完全解析(中)ValueAnimatorObjectAnimator的高階用法

    大家好,在上一篇文章當中,我們學習了Android屬性動畫的基本用法,當然也是最常用的一些用法,這些用法足以覆蓋我們平時大多情況下的動畫需求了。但是,正如上篇文章當中所說到的,屬性動畫對補間動畫進行了很大幅度的改進,之前補間動畫可以做到的屬性動畫也能做到,補間動畫做不到的現在

    Android屬性動畫完全解析(上)初識屬性動畫的基本用法

    fcm 操作 fad 擴展性 改變 內部使用 如果 轉載 @override 轉載請註明出處:http://blog.csdn.net/guolin_blog/article/details/43536355 在手機上去實現一些動畫效果算是件比較炫酷的事情,因此Andr

    Android屬性動畫完全解析 ValueAnimator

    android 屬性動畫完全解析,初識屬性動畫的基本用法:在手機上去實現一些動畫效果算是件比較炫酷的事情,因此Android系統在一開始的時候就給我們提供了兩種實現動畫效果的方式,逐幀動畫(frame-by-frame animation)和補間動畫(tweened anim

    Android屬性動畫原始碼解析

    屬性動畫是Android開發中常用的知識,網上大多數文章都是基於屬性動畫的用法來解說的,本文基於屬性動畫的原始碼,從原始碼角度去一探屬性動畫的究竟。 屬性動畫有兩個非常重要的類,分別是ObjectAnimator和ValueAnimator,其中前者繼承了後者,前者是對屬性動畫的api提供了

    Android 屬性動畫詳解屬性動畫基本用法

    Hello,大家好,今天要給大家講的是Android 屬性動畫詳解! 在Tween動畫的討論中,我們提到在Android中動畫可以分為三類:①幀動畫②Tween(補間動畫)③Property Anim

    android 屬性動畫(view普通使用 自定義view使用)

    1、概述 普通的動畫主要是Animation 和   Animator(與5.0的切換動畫,介面共享元素動畫區分開)  Animation 分 TranslateAnimation 移動 scaleAnimation 縮放 RotateAnimation 旋轉 AlphaA

    Android 屬性動畫(Property Animation) 完全解析 (上)【轉】

    轉載請標明出處:http://blog.csdn.net/lmj623565791/article/details/38067475 1、概述 Android提供了幾種動畫型別:View Animation 、Drawable Animation 、Property Anima

    Android任務返回棧完全解析細數那些你所不知道的細節

    本篇文章主要內容來自於Android Doc,我翻譯之後又做了些加工,英文好的朋友也可以直接去讀原文。任務和返回棧一個應用程式當中通常都會包含很多個Activity,每個Activity都應該設計成為一個具有特定的功能,並且可以讓使用者進行操作的元件。另外,Activity之

    Android 屬性動畫(Property Animation) 完全解析 (上)

    目錄(?)[+] 1、概述 Android提供了幾種動畫型別:View Animation 、Drawable Animation 、Property Animation 。View Animation相當簡單,不過只能支援簡單的縮放、平移、旋轉、透明度基本的動畫,

    Android Service完全解析關於服務你所需知道的一切(上下)

    在上一篇文章中,我們學習了Android Service相關的許多重要內容,包括Service的基本用法、Service和Activity進行通訊、Service的銷燬方式、Service與Thread的關係、以及如何建立前臺Service。以上所提到的這些知識點,基本上涵蓋了大部分日常開發工作當

    Android 屬性動畫(Property Animation) 全然解析 (上)

    顏色 valid 全部 加速度 ext target ng- 點擊 save 轉載請標明出處:http://blog.csdn.net/lmj623565791/article/details/380674751、概述Android提供了幾種動畫類型:View Anima

    Android Service完全解析關於服務你所需知道的一切(下)

    並且 無法 數據類型 界面 其它 wid logcat listen 程序崩潰 文章轉載至:http://blog.csdn.net/guolin_blog/article/details/9797169 這是郭霖寫的.......就是寫 "第一行代碼"的那個厲害人物,大

    Android Service完全解析關於服務你所需知道的一切(上)(筆記)

    參考原文:Android Service完全解析,關於服務你所需知道的一切(上) Service的基本用法 然後新建一個MyService繼承自Service,並重寫父類的onCreate()、onStartCommand()和onDestroy()方法, 可以看到,在Sta

    android動畫四·InterpolatorViewPropertyAnimator用法

    動畫 Interpolator的用法 使用屬性動畫時,系統預設的Interpolator其實就是一個先加速後減速的Interpolator,對應的實現類就是AccelerateDecelerateInterpolator。 9種插值器:(系統預設的)

    十大經典排序算法動畫解析看我就夠了!(配代碼完全版)

    實現 insert 個數 while ets 函數 cep lec nbsp GitHub Repo:Sort Article Follow: MisterBooo · GitHub 排序算法是《數據結構與算法》中最基本的算法之一。 排序算法可以分為內部排序和

    十大經典排序演算法動畫解析看我就夠了!(配程式碼完全版)

    GitHub Repo:Sort Article Follow: MisterBooo · GitHub 排序演算法是《資料結構與演算法》中最基本的演算法之一。 排序演算法可以分為內部排序和外部排序。 內部排序是資料記錄在記憶體中進行排序。 而外部排序是因排序的資料很大,一次不能容納全部的排