Android開發中基礎動畫技巧的應用

Android開發中基礎動畫技巧的應用

1、引言

        我是先入門iOS的移動開發者,提到動畫開發,iOS開發者很容易聯想到3種方式,UIImageView的幀動畫,UIView層的屬性動畫和CoreAnimation動畫。Android中也有3種方式建立基礎動畫效果,分別爲View Animation,Property Animation和Drawable Animation。因爲Android開發的固有特色,其在進行動畫編程時也支持使用代碼和xml配置文件兩種方式。本篇博客,將主要向你們介紹這3種建立Android動畫方式的使用方法與能夠作到的效果。java

2、View Animation動畫的應用

        View Animation又被稱爲Tweened Animation,其應用於View視圖變化的動畫過渡效果。View Animation主要分爲以下4類:android

①.AlphaAnimation:透明度動畫編程

②.RotateAnimation:旋轉動畫ide

③.ScaleAnimation:縮放動畫函數

④.TranslateAnimation:位移動畫動畫

1.AlphaAnimation的應用

    AlphaAnimation用於當視圖透明度發生變化時展現過渡動畫,能夠漸隱也能夠漸現。使用AlphaAnimation建立動畫的核心代碼以下:this

//建立AlphaAnimation動畫對象 構造方法中須要傳入兩個float值 分別是視圖動畫起始的alpha值與最終的alpha值
AlphaAnimation alphaAnimation = new AlphaAnimation(1,0);
//設置動畫執行時間 
alphaAnimation.setDuration(3000);
//調用視圖的startAnimation方法來開啓動畫
animationImageView.startAnimation(alphaAnimation);

2.RotateAnimation的應用

    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);

3.ScaleAnimation的應用

        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構造方法中的參數意義一致。

4.TranslateAnimation的應用

        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軸值。

5.Animation類中的通用方法

        上面介紹的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:自定義運動路徑

6.實現對Animation動畫狀態的監聽

        Animation類中也定義了一個監聽器協議,其中提供了對動畫狀態進行監聽的方法,以下:

public interface AnimationListener {
    //當動畫開始執行時觸發的方法
    void onAnimationStart(Animation var1);
    //動畫執行結束後觸發的方法
    void onAnimationEnd(Animation var1);
    //動畫重複執行的時候會觸發
    void onAnimationRepeat(Animation var1);
}

7.使用xml文件配置View Animation

        上面介紹的所有是經過代碼來建立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);

8.複合的View 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);

3、Property Animation動畫的應用

        在前面介紹的View Animation動畫體系中,雖然使用起來十分方便,但也有十分多的侷限性,例如只能支持透明度,位置,縮放和旋轉動畫,而且在動畫執行時,視圖實際上並無移動,若是須要作動畫的是能夠用戶交互的按鈕控件則會帶來不少的不便。在Android3.0以後,系統推出了Property Animation動畫,這種機制能夠將對象任意屬性的修改實現過渡動畫效果。

1.ObjectAnimator動畫的應用

        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方法。

2.ValueAnimator實現更加靈活的自定義動畫

        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是實實在在的改變了發生動畫控件的屬性。

3.Property Animation動畫的監聽

        ValueAnimator對象可使用addListener()方法來添加監聽者,接口方法以下:

//動畫監聽接口
public interface AnimatorListener {
    //動畫開始
    void onAnimationStart(Animator var1);
    //動畫結束
    void onAnimationEnd(Animator var1);
    //動畫取消
    void onAnimationCancel(Animator var1);
    //動畫重複
    void onAnimationRepeat(Animator var1);
}

4.使用PropertyValuesHolder進行動畫複合

        對於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();

3、Drawable Animation動畫的應用

        相比前兩種動畫模式,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

相關文章
相關標籤/搜索