1. 程式人生 > >Android開發之Tween(補間動畫)完全解析(下)——程式碼實現

Android開發之Tween(補間動畫)完全解析(下)——程式碼實現

在上一篇文章中,我們詳細討論了Tween動畫的xml的實現以及interpolator的使用,相信通過上篇文章大家對Tween動畫的xml屬性的配置會有一個詳細的理解,當然這篇文章也是承接上篇文章,所以強烈建議先閱讀上篇文章:Android開發之Tween(補間動畫)完全解析(上),這篇文章將從程式碼的角度實現上篇文章的效果。如有疑問請留言,如有謬誤歡迎批評指正。

Tween動畫回顧

Tween動畫的分類:alpha(漸變)、scale(縮放)、translate(位移)、rotate(旋轉),這四種動畫都有從Animation繼承過來的公共的方法,又擁有其獨特的方法。其實針對我們在xml中的配置,在Android中都有與其對應的方法。首先來看看與這四種動畫所對應的類

xml根標籤 對應類 動畫型別
alpha AlphaAnimation 漸變透明度動畫
scale ScaleAnimation 漸變縮放動畫
translate TranslateAnimation 漸變位置移動動畫效果
roate RotateAnimation 漸變旋轉動畫效果

首先來看下它們的共有方法,也就是從Animation類繼承的方法

xml屬性 對應的方法 說明
android:duration setDuration(long) 動畫執行時間
android:fillEnabled setFillEnabled(boolean) 與fillBefore結合使用
android:fillBefore setFillBefore(boolean) 動畫結束後是否停留在初始狀態
android:fillAfter setFillAfter(boolean) 動畫結束後是否停留在最後狀態
android:repeatMode setRepeatMode(int) 動畫重複的型別
android:repeatCount setRepeatCount(int) 動畫重複的次數
android:interpolator setInterpolator(Interpolator) 動畫插值器

關於這些屬性在上篇文章已經詳細介紹過,就不再重複了介紹了,瞭解了這些之後,接著就逐一看看這四種動畫吧。

AlphaAnimation

在上篇文章中我們提到在xml檔案配置中alpha動畫的xml檔案配置有:
android:fromAlpha:動畫開始時的透明度,變化範圍為0.0-1.0,0.0表示完全透明,1.0表示完全不透明
android:toAlpha:動畫結束是的透明度,變化範圍和意義同上。
上篇針對alpha動畫,我們的xml檔案的配置為:

<?xml version="1.0" encoding= "utf-8"?>  
<alpha xmlns:android="http://schemas.android.com/apk/res/android"  
        android:fromAlpha= "0.0"  
        android:toAlpha= "1.0"  
        android:repeatCount= "2"  
        android:duration= "3000"  
        android:fillAfter= "true" >  
</alpha>

我們怎樣用程式碼完成與上述xml檔案配置相同的效果呢?其實很簡單,針對alpha動畫所特有的屬性,將設定的資料傳遞到AlphaAnimation的構造方法中即可,AlphaAnimation所有的建構函式如下圖所示:
這裡寫圖片描述
可以看到它一共有兩個建構函式,第一個建構函式我們一般不會用到,這裡主要來看第二個建構函式,可以看到它接收兩個float型別的值,一個是fromAlpha另外一個是toAlpha。也就是在上面xml檔案中配置的,所以要想完成上述xml檔案中的效果,這裡的fromAlpha和toAlpha需要傳的值分別是0和1,表示透明度從完全透明變化到完全不透明。對於公共的屬性的設定,直接呼叫公共的方法進行設定就ok了。所以經過上述分析我們可以想到,上述xml檔案的程式碼實現是下面這樣的

AlphaAnimation alphaAnimation=new AlphaAnimation(0,1);
alphaAnimation.setDuration(3000);
alphaAnimation.setRepeatCount(2);
alphaAnimation.setFillAfter(true);
ivImage.setAnimation(alphaAnimation);

執行效果:
這裡寫圖片描述
可以看到還是不錯的,嗯,對這個妹子不錯。0.0

ScaleAnimaion

ScaleAnimaton的特有的屬性有

屬性 含義
android:fromXScale 起始的X方向上相對自身的縮放比例
android:toXScale 結尾的X方向上相對自身的縮放比例
android:fromYScale 起始的Y方向上相對自身的縮放比例
android:toYScale 結尾的Y方向上相對自身的縮放比例
android:pivotX 縮放起點X軸座標
android:fromYScale 縮放起點Y軸座標

來看看它的建構函式
ScaleAnimation的建構函式圖
看到它一共有四個建構函式,同樣我們只看它的第二、三、四個建構函式,從建構函式中我們可以清楚的看到它建構函式中所需傳的引數基本與xml檔案中的配置一致,其中

ScaleAnimation scaleAnimation=new ScaleAnimation(fromX, toX, fromY, toY, pivotXType, pivotXValue, pivotYType, pivotYValue);

可能大家看到這個建構函式中的兩個引數有點陌生:pivotXType和pivotXValue(這裡以X為例)。我們知道xml檔案中pivotX的取值可以為數值、百分數、百分數p,如50,50%,50%p。當為數值時,表示在當前View的左上角,即原點處加上50px,做為旋轉點X座標;如果是50%表示在當前控制元件的左上角加上自己寬度的50%做為旋轉點X座標;如果是50%p,那麼就是表示在當前控制元件的左上角加上父控制元件寬度的50%做為旋轉點X座標。
這裡的pivotXType就是用來指定我們採取的是哪種數值的。它有三種值:Animation.ABSOLUTE、Animation.RELATIVE_TO_SELF、Animation.RELATIVE_TO_PARENT

取值 意義
Animation.ABSOLUTE 表示取值為數字
Animation.RELATIVE_TO_SELF 表示取值為百分數
Animation.RELATIVE_TO_PARENT 表示取值為百分數p

上篇我們的xml檔案配置如下:

<?xml version="1.0" encoding= "utf-8"?>   
<scale xmlns:android="http://schemas.android.com/apk/res/android"  
       android:fromXScale= "2.0"  
       android:toXScale= "1.0"  
       android:fromYScale= "2.0"  
       android:toYScale= "1.0"  
       android:pivotX= "50%"  
       android:pivotY= "50%"  
       android:duration= "5000">  

</scale> 

通過上面的分析我可以知道它的程式碼實現是:

ScaleAnimation scaleAnimation=new ScaleAnimation(2.0f, 1.0f, 2.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(5000);
ivImage.startAnimation(scaleAnimation);

執行效果圖就不貼了,如果有興趣大家可以動手試試。

TranslateAnimation

TranslateAnimation獨有的屬性:

屬性 意義
android:fromXDelta 起始點X軸座標,可以是數值、百分數、百分數p 三種樣式
android:fromYDelta 起始點Y軸座標,可以是數值、百分數、百分數p 三種樣式
android:toXDelta 結束點X座標
android:toYDelta 結束點Y座標

首先來看看它的建構函式
這裡寫圖片描述
可以看到它有三個建構函式,其中第三個建構函式中fromXType、fromXValue中的fromXType的取值與上面ScaleAnimaion中的pivotXType的取值是一樣的,具體可以看看上面那個表格。
第二個建構函式需要傳遞fromXDelta、toXDelta、fromYDelta、toYDelta,當採用這個建構函式時預設的是使用Animation.ABSOLUTE,對應xml中的取值為數值。
假如xml檔案的配置如下

<?xml version="1.0" encoding= "utf-8"?>  
<translate     xmlns:android="http://schemas.android.com/apk/res/android"   
    android:fromXDelta="0"  
    android:fromYDelta="0"  
    android:toXDelta="200"  
    android:toYDelta="300"  
    android:duration="5000">  
</translate>

通過上面的分析我們應該知道與之效果相同的程式碼實現如下

TranslateAnimation translateAnimation=new TranslateAnimation(Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 200, Animation.ABSOLUTE, 300);
translateAnimation.setDuration(5000);
ivImage.setAnimation(translateAnimation);

RoateAnimation

RoateAnimation獨有的屬性

屬性 意義
android:fromDegrees 動畫開始時旋轉的角度位置,float型別,正值代表順時針方向度數,負值程式碼逆時針方向度數
android:toDegrees 動畫結束時旋轉到的角度位置,float型別,正值代表順時針方向度數,負值程式碼逆時針方向度數
android:pivotX 旋轉點X軸座標,float型別,可以是數值、百分數、百分數p三種樣式
android:pivotY 旋轉點Y軸座標,取值及意義跟android:pivotX一樣

來看看它的建構函式
這裡寫圖片描述
可以看到第二個建構函式中需要兩個引數fromDegrees、toDegrees這個建構函式預設的旋轉的起點是View的左上角的那個點。
第三個建構函式在第二個的基礎之上增加了pivotX和pivotY,用來調整View圍繞旋轉的那個點。它預設的pivotType是Animation.ABSOLUTE及相當於xml中取值為數值。
第四個建構函式就比較全面了,增加了每個值得pivotType與上面ScaleAnimaion中pivotType是一致的。
假如xml檔案中的配置如下:

<?xml version="1.0" encoding= "utf-8"?>  
<rotate xmlns:android="http://schemas.android.com/apk/res/android"  
         android:fromDegrees= "0"  
         android:toDegrees= "360"  
         android:pivotX= "50%"  
         android:pivotY= "50%"  
         android:duration= "10000">  
</rotate> 

通過上面的分析我們應該知道與之對應的程式碼實現如下:

RotateAnimation rotateAnimation=new RotateAnimation(0, 360,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setDuration(3000);
ivImage.startAnimation(rotateAnimation);

Interpolator插值器

為動畫使用插值器也非常簡單,直接呼叫setInterpolator(Interpolator)這個方法就可以了,這裡就以TranslateAnimation新增一個小球回彈的插值器為例進行演示。xml檔案如下

<?xml version="1.0" encoding="utf-8"?>
<translate     xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/bounce_interpolator" 
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:toXDelta="0"
    android:fillAfter="true"
    android:toYDelta="250"
    android:duration="2000">
</translate>

與之對應的程式碼

TranslateAnimation translateAnimation=new TranslateAnimation(Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 250);
translateAnimation.setInterpolator(new BounceInterpolator());
translateAnimation.setFillAfter(true);
translateAnimation.setDuration(2000);

ivDot.startAnimation(translateAnimation);

執行效果如下:
這裡寫圖片描述

AnimationSet

上面我們所討論的都是單個的動畫,當我們需要將幾種動畫同時運用到同一個View的時候,就需要用到AnimationSet這個類了。首先來看看它的建構函式
這裡寫圖片描述
一般我們都是用到第一個建構函式,可以看到它的第一個引數是boolean shareInterpolator從名字也能看出來它的作用是標識是否將AnimationSet中的插值器運用到集合中的所有動畫,為true表示AnimationSet集合中的所有動畫都用AnimationSet中設定的插值器,false表示AnimatonSet集合中的動畫想用哪個動畫,需要自己設定。

<?xml version="1.0" encoding= "utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true">

    <alpha
        android:fromAlpha= "0.0"
        android:toAlpha= "1.0"
        android:duration= "3000" />

    <scale
        android:fromXScale= "0.0"
        android:toXScale= "1.0"
        android:fromYScale= "0.0"
        android:toYScale= "1.0"
        android:pivotX= "50%"
        android:pivotY= "50%"
        android:duration= "3000" />

    <rotate
        android:fromDegrees= "0"
        android:toDegrees= "720"
        android:pivotX= "50%"
        android:pivotY= "50%"
        android:duration= "3000"/>

     <translate
        android:startOffset= "3000"
        android:fromXDelta= "0"
        android:fromYDelta= "0"
        android:toXDelta= "85"
        android:toYDelta= "0"
        android:duration= "1000" />

    <alpha
        android:startOffset= "4000"
        android:fromAlpha= "1.0"
        android:toAlpha= "0.0"
        android:duration= "1000" />

</set>

檢驗的時刻到了,上面是一個比較綜合的動畫,包含了四種類型的動畫,如果能完成上面這個動畫,那Tween動畫掌握的也就差不多了,所以有時間大家最好動手敲敲程式碼,與之對應的程式碼實現如下:

ScaleAnimation scaleAnimation=new ScaleAnimation(0f, 1f, 0f, 1f,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(3000);

RotateAnimation rotateAnimation=new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setDuration(3000);

TranslateAnimation translateAnimation=new TranslateAnimation(Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 85, Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 0);
translateAnimation.setDuration(1000);
translateAnimation.setStartOffset(3000);

AlphaAnimation alphaAnimation=new AlphaAnimation(1f,0f);
alphaAnimation.setDuration(1000);
alphaAnimation.setStartOffset(4000);

AnimationSet animationSet=new AnimationSet(false);
animationSet.addAnimation(scaleAnimation);
animationSet.addAnimation(rotateAnimation);
animationSet.addAnimation(translateAnimation);
animationSet.addAnimation(alphaAnimation);

ivImage.startAnimation(animationSet);

執行效果:
這裡寫圖片描述
效果還算不錯。好了到這裡關於Tween動畫的討論就結束了,希望對你有幫助。鎖定本臺敬請期待下篇,PropertyAnimation屬性動畫完全解析。
如有疑問請留言,如有謬誤歡迎批評指正。