我是先入門iOS的移動開發者,提到動畫開發,iOS開發者很容易聯想到3種方式,UIImageView的幀動畫,UIView層的屬性動畫和CoreAnimation動畫。Android中也有3種方式建立基礎動畫效果,分別爲View Animation,Property Animation和Drawable Animation。因爲Android開發的固有特色,其在進行動畫編程時也支持使用代碼和xml配置文件兩種方式。本篇博客,將主要向你們介紹這3種建立Android動畫方式的使用方法與能夠作到的效果。java
View Animation又被稱爲Tweened Animation,其應用於View視圖變化的動畫過渡效果。View Animation主要分爲以下4類:android
①.AlphaAnimation:透明度動畫編程
②.RotateAnimation:旋轉動畫ide
③.ScaleAnimation:縮放動畫函數
④.TranslateAnimation:位移動畫動畫
AlphaAnimation用於當視圖透明度發生變化時展現過渡動畫,能夠漸隱也能夠漸現。使用AlphaAnimation建立動畫的核心代碼以下:this
//建立AlphaAnimation動畫對象 構造方法中須要傳入兩個float值 分別是視圖動畫起始的alpha值與最終的alpha值 AlphaAnimation alphaAnimation = new AlphaAnimation(1,0); //設置動畫執行時間 alphaAnimation.setDuration(3000); //調用視圖的startAnimation方法來開啓動畫 animationImageView.startAnimation(alphaAnimation);
RotateAnimation用於建立視圖的旋轉動畫。其相比AlphaAnimation要複雜一些,在使用時,除了須要設置其動畫的起始角度和最終角度外,還能夠設置視圖旋轉時的參照位置,示例代碼以下:lua
//建立旋轉動畫對象 RotateAnimation rotateAnimation = new RotateAnimation(0,360, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f); //設置動畫時間 rotateAnimation.setDuration(3000); //開始動畫 animationImageView.startAnimation(rotateAnimation);
這裏使用了RotateAnimation類中最複雜的一個構造方法,其中須要傳入6個參數,前兩個參數分別爲旋轉動畫的起始角度與終止角度,第3個參數爲旋轉參照點的x軸相對位置類型,第4個參數爲參照點x軸位置,第5個和第6個參數分別爲旋轉參照點的y軸相對位置類型與y軸相對位置。spa
關於參照點的相對位置類型,Animation類中定義了幾個常量供開發者選擇使用,意義以下:rest
//絕對定位 以當前窗口作參照 public static final int ABSOLUTE = 0; //以其父視圖作爲位置參照 public static final int RELATIVE_TO_PARENT = 2; //以自己做爲位置參照 public static final int RELATIVE_TO_SELF = 1;
還有一點須要注意,若是選擇的參照類型是RELATIVE_TO_SELF,則參照點的位置參數取值範圍爲0-1之間,表明的是相對於自身的位置比例,若是參照類型是RELATIVE_TO_PARENT,則參照點的位置參數取值範圍爲0-1之間,表明的是相對於父視圖的位置比例,若是參照類型是ABSOLUTE,則參照點的位置參數取值爲絕對座標值,例如100,150,其表明了相對窗口視圖的座標位置。例如上面示例代碼中,以視圖自己爲參照物,x、y軸位置都設置爲0.5,則旋轉動畫以視圖自己中心爲旋轉點,若是須要以視圖右下角爲旋轉點,修改代碼以下:
RotateAnimation rotateAnimation = new RotateAnimation(0,360, Animation.RELATIVE_TO_SELF,1f,Animation.RELATIVE_TO_SELF,1f);
ScaleAnimation用於建立放大或者縮小的形變更畫,示例代碼以下:
//建立縮放動畫對象 ScaleAnimation scaleAnimation = new ScaleAnimation(1,2,1,2,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f); //設置動畫時間 scaleAnimation.setDuration(3000); //執行動畫 animationImageView.startAnimation(scaleAnimation);
上面示例代碼中前4個參數分別設置縮放動畫x軸方向的起始值、最終值和y軸方向的起始值、終止值。須要注意,這裏的單位都是比例,1表示原視圖尺寸,2表示原視圖尺寸的2倍。這個方法後4個參數的意義是肯定縮放參照點的位置,和RotateAniamtion構造方法中的參數意義一致。
TranslateAnimation用於建立位移動畫,示例代碼以下:
//建立位移動畫對象 TranslateAnimation translateAnimation = new TranslateAnimation(Animation.ABSOLUTE,0,Animation.ABSOLUTE,100,Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,1); //設置動畫時間 translateAnimation.setDuration(3000); //執行動畫 animationImageView.startAnimation(translateAnimation);
上面示例代碼中使用的TranslateAnimation構造方法中的8個參數分別表明,起始位置的x軸參照點類型與起始位置的x軸值、終止位置的x軸參照點類型與終止位置的x軸值、起始位置的y軸參照點類型與起始位置的y軸值、終止位置的y軸參照點類型與終止位置的y軸值。
上面介紹的4種動畫實際上都是Animation類的子類,Animation類中封裝了許多動畫通用的方法,例如前面使用的設置動畫執行時間的方法setDuration就是Animation類的方法,其中更多經常使用方法列舉以下:
//取消正在執行的動畫 public void cancel(); //設置動畫的執行函數 public void setInterpolator(Interpolator i); //這隻方法設置開始動畫的延時值 單位爲毫秒 public void setStartOffset(long startOffset); //設置動畫的執行時間 public void setDuration(long durationMillis); //設置動畫特效的最長運行時間 public void restrictDuration(long durationMillis); //設置動畫的執行強度比例 例如放大兩倍的動畫 這個值若是設置爲2 將被放大4倍 public void scaleCurrentDuration(float scale); //爲動畫設置一個開始的時間 public void setStartTime(long startTimeMillis); //設置動畫循環模式 /* 只有當動畫的循環次數大於1時這個值纔有效果,其能夠設置爲以下常量: RESTART 每次循環都從頭執行 REVERSE 正逆交替執行 */ public void setRepeatMode(int repeatMode); //設置循環次數 設置爲INFINITE則爲無限循環 public void setRepeatCount(int repeatCount); //設置是否容許填充動畫 這個方法設置爲true後setFillBefore()與setFillAfter()方法纔會生效 public void setFillEnabled(boolean fillEnabled); //動畫結束後 是否以起始位置填充視圖 public void setFillBefore(boolean fillBefore); //動畫結束後 是否以結束位置填充視圖 public void setFillAfter(boolean fillAfter) //設置動畫執行時在Z軸上的位置 /* 能夠設置爲以下3中常量 public static final int ZORDER_BOTTOM = -1; //將動畫放在Z軸最下邊 public static final int ZORDER_NORMAL = 0; //將動畫放在Z軸原位置 public static final int ZORDER_TOP = 1; //將動畫放在Z軸最上邊 */ public void setZAdjustment(int zAdjustment); //設置動畫的執行是否影響到壁紙 public void setDetachWallpaper(boolean detachWallpaper); //獲取動畫是否開始執行了 public boolean hasStarted(); //獲取動畫是否結束執行了 public boolean hasEnded();
上面列舉的方法中,setInterpolator()方法頗有意思,其能夠設置動畫執行的時間函數,例如是先快後慢仍是先慢後快等等,這個方法須要傳入一個Interpolator類型的參數,實際上使用時是經過Interpolator的子類來實現的,示例以下:
ranslateAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
對於Interpolator參數開發者能夠設置的子類及意義列舉以下:
AccelerateDecelerateInterpolator:先加速後減速執行
AccelerateInterpolator:加速執行
AnticipateInterpolator:前後退執行一步後正向加速執行(相似彈簧效果)
AnticipateOvershootInterpolator:前後退執行一步後加速執行到達極限後再前進一步後再回到極限(彈簧)
BounceInterpolator:動畫執行到結尾後進行阻尼效果
CycleInterpolator:以正弦規則循環執行數次動畫,這個類來構造時須要傳入循環次數,以下:
new CycleInterpolator(3)
DecelerateInterpolator:減速執行動畫
FastOutLinearInInterpolator:基於貝塞爾曲線的速率變化
FastOutSlowInInterpolator:基於貝塞爾曲線的速率變化
LinearInterpolator:線性勻速執行
LinearOutSlowInInterpolator:基於貝塞爾曲線的速率變化
OvershootInterpolator:執行超出極限後在回退
PathInterpolator:自定義運動路徑
Animation類中也定義了一個監聽器協議,其中提供了對動畫狀態進行監聽的方法,以下:
public interface AnimationListener { //當動畫開始執行時觸發的方法 void onAnimationStart(Animation var1); //動畫執行結束後觸發的方法 void onAnimationEnd(Animation var1); //動畫重複執行的時候會觸發 void onAnimationRepeat(Animation var1); }
上面介紹的所有是經過代碼來建立View Animation動畫,Android也支持使用xml文件來配置View Animation動畫。
首先在Android Studio的res目錄中建立一個動畫文件目錄,將其類型選擇爲anim,以下圖所示:
在建立的目錄中建立一個新的xml文件,在其中編寫動畫代碼以下:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <alpha android:fromAlpha="1" android:toAlpha="0" android:duration = "3000"/> </set>
在代碼中,使用以下代碼來加載xml配置的動畫:
//加載動畫文件 Animation animation = AnimationUtils.loadAnimation(this,R.anim.my_anmi); //執行動畫 animationImageView.startAnimation(animation);
View Animation也支持進行復合動畫的操做,若是使用xml配置複合動畫,十分簡單,只須要將要要複合的動畫都配置進xml文件的set標籤中便可,以下:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <alpha android:fromAlpha="1" android:toAlpha="0" android:duration = "3000"/> <scale android:fromXScale="1" android:toXScale="2" android:fromYScale="1" android:toYScale="2" android:duration="3000"/> </set>
若是要用代碼建立複合動畫,須要使用到AnimationSet類進行復合,示例以下:
//建立動畫集合容器 參數決定容器中全部動畫是否共用Interpolator時序函數 AnimationSet set = new AnimationSet(true); //建立動畫 RotateAnimation rotateAnimation = new RotateAnimation(0,360, Animation.RELATIVE_TO_SELF,1f,Animation.RELATIVE_TO_SELF,1f); ScaleAnimation scaleAnimation = new ScaleAnimation(1,2,1,2,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f); scaleAnimation.setDuration(3000); rotateAnimation.setDuration(3000); //將動畫添加進集合中 set.addAnimation(rotateAnimation); set.addAnimation(scaleAnimation); //執行動畫 animationImageView.startAnimation(set);
在前面介紹的View Animation動畫體系中,雖然使用起來十分方便,但也有十分多的侷限性,例如只能支持透明度,位置,縮放和旋轉動畫,而且在動畫執行時,視圖實際上並無移動,若是須要作動畫的是能夠用戶交互的按鈕控件則會帶來不少的不便。在Android3.0以後,系統推出了Property Animation動畫,這種機制能夠將對象任意屬性的修改實現過渡動畫效果。
ObjectAnimator是Property Animation動畫體系中最簡單易用的一種方式,開發者只須要設置要改變的屬性值和一些動畫參數便可使用,例如若要實現視圖以y方向爲軸進行旋轉操做,使用 以下代碼實現:
//建立屬性動畫對象 ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(animationImageView,"rotationY",0,360,0); //設置動畫時間 objectAnimator.setDuration(3000); //開始動畫 objectAnimator.start();
ObjectAnimator類的靜態方法ofFloat()用於建立屬性動畫實例自己,與其相似的方法還有ofInt()與ofObject()。須要注意,這些方法第1個參數爲要執行動畫的視圖,第2個參數爲要發生動畫改變的屬性名,從第3個參數開始後面能夠添加任意多個值,這些值表明了屬性值改變的路徑,例如上面示例代碼表示將視圖以y方向爲軸從0°開始旋轉到360°後再旋轉回0°。
ObjectAnimator類繼承自ValueAnimator,ValueAnimator類則更加靈活自由,其能夠爲自定義類的自定義屬性作動畫處理,後面會介紹,ValueAnimator類中提供了許多動畫配置的方法,經常使用以下:
//設置動畫執行時間 public ValueAnimator setDuration(long duration); //設置延時執行 public void setStartDelay(long startDelay); //設置動畫循環次數 public void setRepeatCount(int value); //設置動畫循環模式 public void setRepeatMode(int value); //設置動畫執行時序模式 public void setInterpolator(TimeInterpolator value); //開始執行動畫 public void start(); //結束動畫 public void end(); //取消動畫 public void cancel(); //恢復動畫 public void resume(); //暫停動畫 public void pause();
須要注意,使用ObjectAnimator建立動畫的屬性必須實現set和get方法。
ObjectAnimator是ValueAnimator的子類,能夠理解,ValueAnimator要比ObjectAnimator更加靈活自由,其能夠實現任意自定義屬性的動畫行爲。示例代碼以下:
//建立ValueAnimator實例 ValueAnimator valueAnimator = new ValueAnimator(); //設置動畫的路徑值 valueAnimator.setFloatValues(0,200,100,300,0); //設置動畫的執行時間 valueAnimator.setDuration(6000); //添加動畫執行監聽 valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { //這個方法會在每次動畫值改變時調用 @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { //設置視圖的橫座標 animationImageView.setX((Float) valueAnimator.getAnimatedValue()); } }); //執行動畫 valueAnimator.start();
若是運行上面代碼,能夠看到視圖在6s內從x座標點爲0的地方平移到200後再次回到100後再次移動到300最終回到原點0。
上面的示例代碼只是演示了ValueAnimator的工做原理,開發者能夠在onAnimationUpdate()方法中進行任意屬性的修改。僅從上面演示代碼並不能體現出ValueAnimator的強大之處,能夠經過實現相似拋物線的動畫來理解ValueAnimator的靈活之處,示例代碼以下:
//建立ValueAnimator實例 final ValueAnimator animator = new ValueAnimator(); //示例進行拋物線動畫 讓控件從(0,0)點位置移動到x軸爲400的位置,y軸方向作自由落體 animator.setObjectValues(new Point(0,0),new Point(400,0)); //設置動畫時間 animator.setDuration(4000); //設置時序爲線性函數 animator.setInterpolator(new LinearInterpolator()); //因爲拋物線運動在x軸和y軸上的速度變化並不相同 須要自定義枚舉器 animator.setEvaluator(new TypeEvaluator<Point>() { //這個枚舉方法中傳入的v值爲動畫執行的比例 0爲初始狀態 1爲動畫執行完成 開發者根據這個值模擬拋物線座標 @Override public Point evaluate(float v, Point o,Point t1) { //建立Point對象 模擬拋物運動 Point point = new Point(); point.x = (int)((v*8)*100); point.y = (int)((v*60)*(v*60)/4); return point; } }); //監聽動畫執行 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { //設置視圖位置 animationImageView.setX(((Point)valueAnimator.getAnimatedValue()).x); animationImageView.setY(((Point)valueAnimator.getAnimatedValue()).y); } }); //執行動畫 animator.start();
須要注意,Property Animation與View Animation最大的不一樣在於View Animation只是展現視圖的界面動畫,它並無真正改變視圖的屬性,而Property Animation是實實在在的改變了發生動畫控件的屬性。
ValueAnimator對象可使用addListener()方法來添加監聽者,接口方法以下:
//動畫監聽接口 public interface AnimatorListener { //動畫開始 void onAnimationStart(Animator var1); //動畫結束 void onAnimationEnd(Animator var1); //動畫取消 void onAnimationCancel(Animator var1); //動畫重複 void onAnimationRepeat(Animator var1); }
對於Property Animation,開發者能夠經過ValueAnimator實現自定義的複合動畫,也可使用PropertyValuesHolder進行屬性動畫的複合操做,示例以下:
//建立子屬性動畫 翻轉 PropertyValuesHolder holder = PropertyValuesHolder.ofFloat("rotationY",0,360,90); //建立子屬性動畫 透明 PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("alpha",1,0,1); //進行動畫複合 ObjectAnimator objectAnimation = ObjectAnimator.ofPropertyValuesHolder(animationImageView,holder,holder2); //執行動畫 objectAnimation.setDuration(3000); objectAnimation.start();
相比前兩種動畫模式,Drawable Animation動畫要容易的多,其使用一組圖像快速切換的原理來實現動畫效果。
在Android Studio的drawable文件夾中添加一個animation文件,xml代碼以下:
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/bird1" android:duration="200" /> <item android:drawable="@drawable/bird2" android:duration="200" /> <item android:drawable="@drawable/bird3" android:duration="200" /> <item android:drawable="@drawable/bird4" android:duration="200" /> <item android:drawable="@drawable/bird5" android:duration="200" /> <item android:drawable="@drawable/bird6" android:duration="200" /> <item android:drawable="@drawable/bird7" android:duration="200" /> <item android:drawable="@drawable/bird8" android:duration="200" /> </animation-list>
將須要展現動畫的視圖背景設置爲這個drawable文件,示例以下:
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/anmi_draw_list" android:id="@+id/animatedImageView"/>
在須要開始動畫時,調用以下代碼便可:
//獲取到drawable背景 調用start()方法開始動畫 ((AnimationDrawable)animationImageView.getBackground()).start();
專一技術,熱愛生活,交流技術,也作朋友。
——琿少 QQ羣:435043639