Android—逐幀、補間、屬性動畫

1、Tween Animation 補間動畫

      這類動畫比較簡單,一般就是平移、縮放、旋轉、透明度,或者其組合,可以用代碼或者xml文件的形式,推薦使用xml文件形式,因爲可以複用。

      四個動畫效果實現類:TranslateAnimation、ScaleAnimation、RotateAnimation、AlphaAnimation、AnimationSet,對應的的XML標籤爲translate、 scale、 rotate、alpha、set,其中set裏還可以放set,然後放在放置在res/anim/目錄下,關於詳細使用這裏不再做介紹。

1.alpha漸變透明度動畫效果

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"                //動畫持續時間    
    android:fromAlpha="1.0"               //透明度變化
    android:toAlpha="0.0" />

2.scale漸變尺寸縮放動畫效果

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromXScale="0.0"            // 動畫開始前X,Y的縮放,0.0爲不顯示, 1.0爲正常大小
    android:fromYScale="0.0"
    android:interpolator="@android:anim/decelerate_interpolator"      //動畫插入器
    android:pivotX="50%"                //屬性爲動畫相對於物件的X,Y座標的開始位置
    android:pivotY="50%"                //兩個都爲50%表示動畫從自身中間開始
    android:repeatCount="1"             //動畫重複的計數,動畫將會執行該值+1次
    android:repeatMode="reverse"        //動畫重複的模式,reverse爲反向   
    android:startOffset="0"             //動畫多次執行的間隔時間,若執行一次,執行前會暫停這段時間,單位毫秒
    android:toXScale="1.5"              //動畫最終縮放的倍數, 1.0爲正常大小,大於1.0放大
    android:toYScale="1.5" />

3.rotate畫面旋轉動畫效果

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromDegrees="0"            //動畫開始時的角度            
    android:toDegrees="-360"           //動畫結束時物件的旋轉角度,正代表順時針
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:pivotX="50%"               //屬性爲動畫相對於物件的X,Y座標的開始位置
    android:pivotY="50%"/>        

4.translate畫面位置移動動畫效果

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromXDelta="100"            //起始時X,Y座標,屏幕右下角的座標是X:320,Y:480
    android:fromYDelta="0"                
    android:interpolator="@android:anim/cycle_interpolator"
    android:toXDelta="0"                //動畫結束時X,Y的座標
    android:toYDelta="0" />

5.set組合動畫效果

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha
        android:duration="500"
        android:fromAlpha="1.0"
        android:toAlpha="0.0" />

    <scale
        android:fromXScale="0.0"
        android:toXScale="1.5"/>
</set>

動畫監聽器Animation.AnimationListener:

 有時可能我們要在動畫的每個週期裏面做不同的操作,這時候就要藉助動畫監聽器了

alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
    @Override
    public void onAnimationStart(Animation animation) {
        //動畫開始時調用
    }

    @Override
    public void onAnimationEnd(Animation animation) {
        //動畫結束時調用
    }

    @Override
    public void onAnimationRepeat(Animation animation) {
        //動畫重複時調用
    }
    });

幾種自帶的動畫插入器

AccelerateInterpolator 加速,開始時慢中間加速

DecelerateInterpolator 減速,開始時快然後減速

AccelerateDecelerateInterolator 先加速後減速,開始結束時慢,中間加速

AnticipateInterpolator 反向,先向相反方向改變一段再加速播放

AnticipateOvershootInterpolator 反向加超越,先向相反方向改變,再加速播放,會超出目的值然後緩慢移動至目的值

BounceInterpolator 跳躍,快到目的值時值會跳躍,如目的值100,後面的值可能依次爲85,77,70,80,90,100

CycleIinterpolator 循環,動畫循環一定次數,值的改變爲一正弦函數:Math.sin(2* mCycles* Math.PI* input)

LinearInterpolator 線性,線性均勻改變

OvershootInterpolator超越,最後超出目的值然後緩慢改變到目的值

2、Frame Animation(Drawable Animation)逐幀動畫

  如果要做很炫酷的下拉刷新或者loading動畫,可以考慮使用Airbnb開源的動畫框架Lottie
  簡單講就是把幾個靜態的圖片快速播放形成動畫,可以使用AnimationDrawable,官方推薦使用XML文件,放在res/drawable/路徑下。

具體實現過程:

1.在res/drawable目錄下一個xml文件:

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item
        android:drawable="@mipmap/lottery_1"
        android:duration="200" />
    <item
        android:drawable="@mipmap/lottery_2"
        android:duration="200" />
    <item
        android:drawable="@mipmap/lottery_3"
        android:duration="200" />
</animation-list>

根節點是animation-list(動畫列表),裏面有一個或者多個item節點組成,oneshot屬性表示是否只播放一次,true表示只會播放一次,false表示一直循環播放,內部用item節點聲明一個動畫幀,android:drawable指定此幀動畫所對應的圖片資源,android:druation代表此幀持續的時間,整數,單位爲毫秒。

2.用ImageView控件作爲動畫載體來顯示動畫:

imageView.setImageResource(R.drawable.lottery_animlist);
AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getDrawable();
animationDrawable.start();

animationDrawable.stop();

onCreate方法中我們運行一下,發現動畫沒有運行而是停留在第一幀,那是因爲AnimationDrawable播放動畫是依附在window上面的,而在Activity onCreate方法中調用時Window還未初始化完畢,所有才會停留在第一幀,要想實現播放必須在onStart或者onWindowFocusChanged中調用start方法。

總結:

   Frame Animation(逐幀動畫)相對來說比較簡單,但是在實際開發中使用的頻率還是比較高的。希望以這個小例子能夠掌握逐幀動畫,但是逐幀動畫只能實現比較小的動畫效果,如果複雜而且幀數比較多的動畫不太建議使用逐幀動畫,一方面是因爲會造成OOM,另一方面會顯得很卡,如果真是超級複雜的動畫的話建議選擇雙緩衝繪製View來實現。

3.Property Animation  屬性動畫

Property Animation產生的背景:

補間動畫只是改變了View對象繪製的位置,而沒有改變View對象本身, 如果要實現既要有動畫效果又要使得View本身得到真正改變,那就要藉助屬性動畫了,這也是屬性動畫引入的原因。它能夠更加靈活的實現各種效果,不僅限於類似補間動畫實現的哪幾種效果。

Property Animation相關類

   屬性動畫,根據字面理解可以通過修改物件的屬性值以達到動畫效果。

類名 用途
ValueAnimator 屬性動畫主要的計時器,也計算動畫後的屬性的值,動畫的執行類
ObjectAnimator   ValueAnimator的一個子類,允許你設置一個目標對象和對象的屬性進行動畫,動畫的執行類
AnimatorSet 提供組織動畫的結構,使它們能相關聯得運行,用於控制一組動畫的執行
AnimatorInflater  用戶加載屬性動畫的xml文件
Evaluators  屬性動畫計算器,告訴了屬性動畫系統如何計算給出屬性的值
Interpolators 動畫插入器,定義動畫的變化率

 

ObjectAnimator:

   ValueAnimator的一個子類,允許你設置一個目標對象和對象的屬性進行動畫。當這個類計算好一個動畫的新值後,相應的會更新其屬性。大多數時候你都會想用ObjectAnimator,因爲它使得動畫值到目標對象的處理更簡單了。

1.以實現一個View透明漸變效果爲例進行說明

這裏需要注意是的屬性動畫文件存放目錄爲res/animator

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:propertyName="alpha"      //表示修改的物件的哪個屬性值,這裏是透明度
    android:repeatCount="1"            
    android:repeatMode="reverse" 
    android:startOffset="200"         //動畫多次執行的間隔時間,如果只執行一次,執行前會暫停這段時間,單位毫秒 
    android:valueFrom="0.0"           //表示從哪個狀態值開始動畫
    android:valueTo="1.0"             //表示到哪個狀態值結束動畫
    android:valueType="floatType" />  //類型估值,主要用於設置動畫操作屬性的值

通過上面的xml屬性可以看出和補間動畫基本上一致,然後通過AnimatorInflater 來加載xml中的動畫

也可以用java實現

ObjectAnimator alphaAnimation = ObjectAnimator.ofFloat(imageView, "alpha", 0f, 1f);
    alphaAnimation.setDuration(500);
    alphaAnimation.setRepeatCount(0);
    alphaAnimation.setRepeatMode(ValueAnimator.REVERSE);
    alphaAnimation.setStartDelay(200);
    alphaAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
    alphaAnimation.start();

ObjectAnimator 提供了以下幾個方法:ofFloat(),ofInt(),ofObject(),ofArgb(),ofPropertyValuesHolder()這幾個方法都是設置動畫作用的元素、作用的屬性、動畫開始、結束、以及中間的任意個屬性值。 

Animator anim = AnimatorInflater.loadAnimator(this, R.animator.animator_alpha);
anim.setTarget(imageView);
anim.start();

2.如何實現一個組合動畫

    舉例我們同時對一個控件進行寬高兩個維度的縮放

  方式一:使用AnimatorSet

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="together">
    <objectAnimator
        android:duration="500"
        android:propertyName="scaleX"
        android:repeatCount="1"
        android:repeatMode="reverse"
        android:valueFrom="1.0"
        android:valueTo="1.5"
        android:valueType="floatType" />
    <objectAnimator
        android:duration="500"
        android:propertyName="scaleY"
        android:repeatCount="1"
        android:repeatMode="reverse"
        android:valueFrom="1.0"
        android:valueTo="1.5"
        android:valueType="floatType" />

</set>

方式二:使用PropertyValuesHolder


PropertyValuesHolder scaleXValuesHolder = PropertyValuesHolder.ofFloat("scaleX", 1.0f, 1.5f);
PropertyValuesHolder scaleYValuesHolder = PropertyValuesHolder.ofFloat("scaleY", 1.0f, 1.5f);
ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(imageView, scaleXValuesHolder, scaleYValuesHolder);
    objectAnimator.setDuration(500);
    objectAnimator.setRepeatCount(1);
    objectAnimator.setRepeatMode(ValueAnimator.REVERSE);
    objectAnimator.start();

通過這種方式只能實現同時執行的動畫組合相比AnimatorSet就沒那麼豐富了,PropertyValuesHolder 提供的函數方法有如下幾種:ofInt()、ofFloat()、ofObject()、ofKeyframe()。

方式三:使用ViewPropertyAnimator

 ViewPropertyAnimator viewPropertyAnimator=imageView.animate();
 viewPropertyAnimator.scaleXBy(1.0f).scaleX(1.5f).scaleYBy(1.0f).scaleY(1.5f).setDuration(500).start();

多屬性動畫,作用於View,能夠實現的動畫相對單一,只能實現比如縮放,透明度改變,平移、旋轉等,具體函數名字:平移 translationX,translationY, X,Y,縮放 scaleX,scaleY, 旋轉 rotationX, rotationY,透明度 alpha

objectAnimator.addListener同樣可以設置監聽器

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