View動畫、幀動畫

稀飯_發表於2018-07-02

Android的動畫可以分為三種:View動畫幀動畫屬性動畫。

  • View動畫包括:平移、旋轉、縮放、透明度。不會改變控制元件座標引數
  • 幀動畫:圖片切換動畫。不會改變控制元件座標引數
  • 屬性動畫:通過動態改變控制元件的屬性(改變控制元件部分座標引數達到動畫效果。

一 View動畫的建立步驟和方式

 View動畫的四種變換效果對應著Animation的四個子類,分別是:TranslateAnimationRotateAnimationScaleAnimationAlphaAnimation。這四種動畫既可以通過XML來定義,也可以通過程式碼來動態建立。他們的整合關係如下:

View動畫、幀動畫

通過xml去建立動畫的步驟:

1.在res資料夾下建立anim資料夾 

2.在anim資料夾下去建立動畫xml檔案

3.通過AnimationUtils類的靜態方法loadAnimation獲取動畫物件

4.通過View.startAnimation()方法開啟動畫;

通過程式碼去建立動畫的步驟(這裡不寫具體的步驟):

1.建立TranslateAnimation、RotateAnimation、ScaleAnimation或AlphaAnimation物件;

2.設定建立的動畫物件的屬性,如動畫執行時間、延遲時間、起始位置、結束位置等;

3.通過View.startAnimation()方法開啟動畫;

二 TranslateAnimation動畫

建立一個動畫xml檔案

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:toXDelta="300"
    android:toYDelta="300" />複製程式碼

解釋一下屬性:

這裡的座標系是以控制元件自身的左上角為座標原點,右下為正方向的座標系

android:fromXDelta:動畫開始時候X方向的座標

android:fromYDelta:動畫開始時候Y方向的座標

android:toXDelta:動畫結束時候X方向的座標

android:toYDelta:動畫結束時候Y方向的座標

它們的值不僅可以指定畫素,而且還可以指定百分比,且座標系的原點不會改變!

相對於自身可以指定像這樣:

   android:toXDelta="100%"複製程式碼

相對於父控制元件可以指定像這樣

   android:toXDelta="100%p"複製程式碼

 android:duration:一個動畫週期持續時間,單位是ms

 android:fillAfter :設定為true,動畫結束時,將保持動畫最後時的狀態

 android:fillBefore :設定為true,動畫結束時,還原到開始動畫前的狀態,預設值

 android:repeatCount :重複次數,想讓永遠設定成-1

android:repeatMode :重複型別,有reverse和restart兩個值,reverse表示倒序回放,restart表示重新放一遍,必須與repeatCount一起使用才能看到效果。因為這裡的意義是重複的型別,即回放時的動作。預設不寫是restart效果

android:startOffset:動畫延遲執行的時間,單位是ms

android:interpolator:動畫插值器,改變動畫播放速率

插值器的值有:

@android:anim/accelerate_interpolator:加速變化(開始慢,越來越快)

@android:anim/decelerate_interpolator:減速變化(開始快,越來越慢)

@android:anim/accelerate_decelerate_interpolator:先加速後減速(中間速度最快)

@android:anim/linear_interpolator:線性均勻變化

@android:anim/overshoot_interpolator:超出結尾的臨界值,然後在緩慢回到結束值

@android:anim/anticipate_interpolator:先向相反的方向改變一點,然後加速變化

@android:anim/anitcipate_overshoot_interpolator:先向相反的方向改變一點,然後在加速播放至超出結束值一點,然後在緩慢回到結束值

@android:anim/bounce_interpolator:動畫快結束的時候,模擬球落地的回彈效果

@android:anim/cycle_interpolator:反方向在做一次動畫效果

程式碼載入xml去開啟動畫程式碼:

//載入xml動畫
val translate1 = AnimationUtils.loadAnimation(this, R.anim.translate1)
//給控制元件設定動畫並開啟
btn.startAnimation(translate1)複製程式碼

RotateAnimation動畫

建立一個動畫xml檔案

<?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="-300"
    android:pivotX="50%"
    android:pivotY="50%">

</rotate>複製程式碼

解釋一下屬性:

這裡的夾角是和Y軸的夾角,順時針為正,逆時針為負,座標系還是當前控制元件的左上角為原點

android:fromDegrees:開始動畫的角度

android:toDegrees:結束時候的角度

android:pivotY,android:pivotX:旋轉的中心點座標,不寫是控制元件的左上角原點為中心點

其餘的屬性和平移動畫一樣,不再重複

四 ScaleAnimation動畫

建立一個動畫xml檔案

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

</scale>複製程式碼

解釋一下屬性:

座標系還是當前控制元件的左上角為原點

android:fromYScale,android:fromXScale:開始縮放比例

android:toXScale, android:toYScale:結束縮放比例

android:toYScale,android:pivotY:縮放中心點

其餘的屬性和平移動畫一樣,不再重複

五AlphaAnimation動畫

<?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">

</alpha>複製程式碼

解釋一下屬性:

android:fromAlpha:動畫開始時候透明度

android:fromAlpha:動畫結束時候透明度

其餘的屬性和平移動畫一樣,不再重複

六組合到一起

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

    <translate
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="0"
        android:toYDelta="300" />

    <rotate
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="300" />

    <scale
        android:fromXScale="0"
        android:fromYScale="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1"
        android:toYScale="1" />
    <alpha
        android:fromAlpha="0"
        android:toAlpha="1" />
</set>複製程式碼

這裡有兩個細節需要注意:

  • 如果我們給set設定了共有的屬性,那麼它包裹的動畫再次設定這個屬性也不會生效,都會以跟屬性為準。
  • 但是插值器可以單獨設定,需要配合android:shareInterpolator一起設定,表示集合中的動畫是否和集合共享同一個插值器。
  • 如果不想讓組合動畫同時執行,我們可以通過設定動畫的延遲時間去改變不去同時執行,它並沒有像屬性動畫那樣給我們提供設定執行先後順序的方法。

七View動畫的監聽

val loadAnimation = AnimationUtils.loadAnimation(this, R.anim.enter)
loadAnimation.setAnimationListener(object : Animation.AnimationListener {
    //動畫完全結束時候呼叫
    override fun onAnimationEnd(animation: Animation?) {

    }

    //動畫開始時候呼叫
    override fun onAnimationStart(animation: Animation?) {
    }

    //動畫重複時候呼叫
    override fun onAnimationRepeat(animation: Animation?) {

    }
})複製程式碼

八幀動畫

幀動畫是順序播放一組預先定義好的圖片,類似於電影播放。幀動畫建立的檔案在drawable資料夾下。需要用到的類是AnimationDrawable。它的繼承關係如下:

View動畫、幀動畫


<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">

    <item android:drawable="@drawable/d_beishang" android:duration="500" />
    <item android:drawable="@drawable/d_bishi" android:duration="500" />
    <item android:drawable="@drawable/d_bizui" android:duration="500" />
    <item android:drawable="@drawable/d_chanzui" android:duration="500" />

</animation-list>複製程式碼
//把定義的幀動畫設定給控制元件
btn.setBackgroundResource(R.drawable.donghua);
//獲取控制元件中的幀動畫
var anim = btn.background as AnimationDrawable
//開啟幀動畫
anim.start()複製程式碼

解釋: android:oneshot屬性表示是否重複動畫,

注意:幀動畫的使用比較簡單,但是比較容易引起OOM。

九view動畫常見應用場景

8.1 5.0版本之前Activity切換動畫

主要用到 overridePendingTransition(int enterAnim,int exitAnim)這個方法,這個方法必須在 startActivity(Intent)或者finish()之後被呼叫才能生效。這裡自定義的view動畫設定到裡邊就能替換原生系統的切換動畫。

延伸:5.0版本之後google對於切換介面動畫提供了新的方式

8.2給ViewGroup的子控制元件加進場動畫

這種效果需要用到layoutAnimation類,步驟如下:

1.建立res/anim下view動畫

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="0"
        android:toXDelta="0"
        android:fromYDelta="100%"
        android:toYDelta="0"
        android:duration="2000" />
    <alpha
        android:fromAlpha="0"
        android:toAlpha="1"
        android:duration="2000" />
</set>複製程式碼

2.在res/anim下建立layoutAnimation

<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
    android:delay="0.5"
    android:animationOrder="normal"
    android:animation="@anim/anim_layout">

</layoutAnimation>複製程式碼

解釋屬性:

 android:delay:可以取值為數值,百分數,或百分數p。表示兩個子控制元件執行出場動畫的間隔時間,為0時,所有控制元件的動畫沒有延遲全部開始執行;為1時表示等上一個控制元件動畫執行完畢才開始執行下一個

 android:animationOrder:有三個值::normal表示按正常順序出現。random表示亂序出現。reverse表示反序出現。

 android:animation:指定出現時要執行的view動畫

3.給viewGroup設定layoutAnimation的值

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layoutAnimation="@anim/layout_viewgrop"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

      ...
</LinearLayout>複製程式碼

同時可以用程式碼設定子view的動畫:

//載入組定義的view動畫
val loadAnimation = AnimationUtils.loadAnimation(this, R.anim.anim_layout)
//建立動畫控制器
val Controller = LayoutAnimationController(loadAnimation)
//設定每個子view動畫間隔
Controller.delay=0.5F
//設定動畫播放順序
Controller.order = LayoutAnimationController.ORDER_NORMAL
//把動畫設定給父控制元件
viewGroup.layoutAnimation = Controller複製程式碼


相關文章