Android動畫學習之——補間動畫

本文摘自博友野狗道人,博文地址:https://www.cnblogs.com/glimpse/p/5256182.html

介紹:

補間動畫是一種設定動畫開始狀態、結束狀態,其中間的變化由系統計算補充。這也是他叫做補間動畫的原因。

補間動畫由Animation類來實現具體效果,包括平移(TranslateAnimation)、縮放(ScaleAnimation)、旋轉(RotateAnimation)、透明度(AlphaAnimation)四個子類,四種變化。

 

實現:

補間動畫的四種變化效果(四個類)允許通過xml設置,也可以通過初始化類來設置。xml比較簡單,java比較靈活。

1、通過xml設置補間動畫

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@[package:]anim/interpolator_resource"
    android:shareInterpolator=["true" | "false"] >
    <alpha
        android:fromAlpha="float"
        android:toAlpha="float" />
    <scale
        android:fromXScale="float"
        android:toXScale="float"
        android:fromYScale="float"
        android:toYScale="float"
        android:pivotX="float"
        android:pivotY="float" />
    <translate
        android:fromXDelta="float"
        android:toXDelta="float"
        android:fromYDelta="float"
        android:toYDelta="float" />
    <rotate
        android:fromDegrees="float"
        android:toDegrees="float"
        android:pivotX="float"
        android:pivotY="float" />
    <set>
        ...
    </set>
</set>

 

android:interpolator爲動畫的變化速度【可以單獨設置,可以直接放在set裏面】
  可以設置多種速度變化方式,這裏只列出勻速、加速、減速
  勻速  @android:anim/linear_interpolator
  加速  @android:anim/accelerate_interppolator
  減速 @android:anim/decelerate_interpolator

android:shareInterpolator爲是否給所有子元素共享動畫變化速度【放在set裏面設置是否共享】


android:fillAfter動畫顯示結束保持最後一幀【true:最後一幀】
android:fillBefore動畫顯示結束保持第一幀【true:第一幀】


android:duration動畫播放時間【單位毫秒,每個動畫都需要設置,否則沒有效果】


android:startOffset動畫裝載完成後需要等待多少時間才能啓動【單位毫秒】


透明度
android:fromAlpha爲動畫開始的透明度【0:完全透明,1:完全不透明】
android:toAlpha爲動畫結束的透明度
縮放
android:fromXScale、android:fromYScale爲動畫開始X,Y方向上的縮放比例【0:小的沒有,1:原本大小】
android:toXScale、android:toYScale爲動畫開始X,Y方向上的縮放比例
android:pivotX、android:pivotY爲動畫在X,Y方向上的縮放中心點(比如設置爲0,0那麼就是寬和高向左上角縮小)【例如:50%是距左邊界圖片一半的距離】


平移
android:fromXDelta、android:fromYDelta爲動畫平移的起始點
android:toXDelta、android:toYDelta爲動畫平移的結束點

旋轉
android:fromDegrees爲動畫旋轉的起始角度【0:不動,180:轉半圈,360:轉一圈,3600:轉10圈,-180逆時針轉半圈】
android:toDegrees爲動畫旋轉的結束角度
android:pivotX、android:pivotY爲動畫旋轉的中心點【例如:50%是距左邊界圖片一半的距離】

以上每一個都可以在java代碼中通過setXXX來設置。

通過xml新建完動畫資源還需要使用AnimationUtils進行裝載。
final Animation anim = AnimationUtils
            .loadAnimation(this, R.anim.anim);

上面的R.anim.anim就是上面用xml寫出來的動畫文件。

 

其實補間動畫是一種View Animation,是專門作用在View上的。

所以在我們使用的時候,直接調用View的startAnimation方法就好了。

flower.startAnimation(reverse);

代碼中的flower是一個ImageView。


2、除了使用xml定義動畫以外,還可以直接新建一個相應的對象。

新建對象時構造函數的參數和上面的xml是一樣的,就不詳細介紹了~

平移(TranslateAnimation)
構造函數
public TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,
            int fromYType, float fromYValue, int toYType, float toYValue)
fromXType、toXType、fromYType、toYType指的是座標類型,默認爲ABSOLUTE,如果使用絕對座標的話可以省去type這個參數。基本上使用這個參數都是爲了設置爲RELATIVE_TO_SELF,意思是相對有自己的距離。
剩下的那些值就好xml裏一樣,自己就能看懂啦~

下面是具體的使用:
TranslateAnimation translateAnimation = 
                    new TranslateAnimation(
                            Animation.RELATIVE_TO_SELF, 0f,
                            Animation.RELATIVE_TO_SELF, 0.5f,
                            Animation.RELATIVE_TO_SELF, 0f,
                            Animation.RELATIVE_TO_SELF, 0.5f
                    );
            translateAnimation.setDuration(5000);
            image.startAnimation(translateAnimation);

 

 

縮放(ScaleAnimation)
構造函數:
public ScaleAnimation(float fromX, float toX, float fromY, float toY,
            int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
pivotXType、pivotYType指的是座標類型,默認爲ABSOLUTE,如果使用絕對座標的話可以省去type這個參數。基本上使用這個參數都是爲了設置爲RELATIVE_TO_SELF,意思是相對有自己的距離。
下面是具體的使用:
ScaleAnimation scaleAnimation = new ScaleAnimation( 0, 1f, 0, 1f, Animation.RELATIVE_TO_SELF,0.5f);
            scaleAnimation.setDuration(5000);
            image.startAnimation(scaleAnimation);
旋轉(RotateAnimation)
構造函數:
public RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,
            int pivotYType, float pivotYValue)
pivotXType、pivotYType指的是座標類型,默認爲ABSOLUTE,如果使用絕對座標的話可以省去type這個參數。基本上使用這個參數都是爲了設置爲RELATIVE_TO_SELF,意思是相對有自己的距離。
具體使用:
RotateAnimation rotateAnimation = new RotateAnimation( 0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5F);
            rotateAnimation.setDuration(1000);
            image.startAnimation(rotateAnimation);
透明度(AlphaAnimation)
構造函數:
public AlphaAnimation(float fromAlpha, float toAlpha)
具體使用:
AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
            alphaAnimation.setDuration(5000);
            image.startAnimation(alphaAnimation);

 

Animation類介紹

既然補間動畫的四種變化都是基於Animation寫的,那麼我們是不是也可以自定義一個補間動畫呢。

當然可以。

 

其實Animation類最主要的函數是applyTransformation,重寫這個函數就可以實現自己的動畫啦~

protected void applyTransformation(float interpolatedTime, Transformation t)
interpolatedTime:代表動畫的時間進行比,不管實際持續時間是多少,當動畫播放時,該參數總是從0到1
Transformation :這個參數是補間動畫在不同時刻的變化,具體的變化都是通過這個參數實現。這個對象裏面封裝了一個Matrix,所以可以直接使用Matrix的函數實現對View的各種操作。
幹說也不明白,我們直接看一下RotateAnimation的代碼吧~
@Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        float degrees = mFromDegrees + ((mToDegrees - mFromDegrees) * interpolatedTime);
        float scale = getScaleFactor();
        
        if (mPivotX == 0.0f && mPivotY == 0.0f) {
            t.getMatrix().setRotate(degrees);
        } else {
            t.getMatrix().setRotate(degrees, mPivotX * scale, mPivotY * scale);
        }
    }

 

這個函數可能是能夠不斷的裝載吧(這他媽做麼做到的,誰知道的話在評論裏告訴我!!),在不同的時間通過運算就能夠得到不同的角度,然後設置相應的旋轉角度。

 

由於Matrix提供傾斜函數,我們可以寫一個傾斜的動畫。雖然可能沒有什麼實際用處。

代碼貼在下面,我就這麼隨便一寫,更多玩法等待你的開發哦~

package activity;

import android.view.animation.Animation;
import android.view.animation.Transformation;

public class MyAnimation extends Animation{
    
    private float mkx;
    private float mky;
    
    
    public MyAnimation(float kx, float ky)
    {
        this.mkx = kx;
        this.mky = ky;
    }
    
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        float kx = mkx * interpolatedTime;
        float ky = mky * interpolatedTime;
        
        t.getMatrix().setSkew(kx, ky);
        
    }

}
 

 

我在學習安卓時的教材用的是《安卓瘋狂講義》,他在這裏講了控制三維變換的類Camera,也可以使用這個類來實現動畫三維變換。

關於這個類的具體信息大家可以看一下官網:http://developer.android.com/reference/android/graphics/Camera.html

常用的幾個函數列一下:

getMatrix(Matrix matrix):將Camera所做的變換用用到matrix上

rotate(float x, float y, float z):三個方向上的變換

rotateX(float deg):將目標組件沿X軸旋轉

rotateY(float deg):將目標組件沿Y軸旋轉

rotateZ(float deg):將目標組件沿Z軸旋轉

translate(float x,float y,float z):把目標組件在三維空間內進行位移變換

applyToCanvas(Canvas canvas):把Camera所做變幻應用到Canvas上

save():保存Camera的狀態

 

。。。

 

然後大家就看一下我這本書上他們自定義的動畫吧~

複製代碼

public class MyAnimation extends Animation
{
    private float centerX;
    private float centerY;
    // 定義動畫的持續事件
    private int duration;
    private Camera camera = new Camera();

    public MyAnimation(float x, float y, int duration)
    {
        this.centerX = x;
        this.centerY = y;
        this.duration = duration;
    }

    @Override
    public void initialize(int width, int height
        , int parentWidth, int parentHeight)
    {
        super.initialize(width, height, parentWidth, parentHeight);
        // 設置動畫的持續時間
        setDuration(duration);
        // 設置動畫結束後效果保留
        setFillAfter(true);
        setInterpolator(new LinearInterpolator());
    }

    /*
     * 該方法的interpolatedTime代表了抽象的動畫持續時間,不管動畫實際持續時間多長,
     * interpolatedTime參數總是從0(動畫開始時)~1(動畫結束時) 
     * Transformation參數代表了對目標組件所做的變.
     */
    @Override
    protected void applyTransformation(float interpolatedTime
        , Transformation t)
    {
        camera.save();
        // 根據interpolatedTime時間來控制X、Y、Z上的偏移
        camera.translate(100.0f - 100.0f * interpolatedTime,
                150.0f * interpolatedTime - 150,
                80.0f - 80.0f * interpolatedTime);
        // 設置根據interpolatedTime時間在Y柚上旋轉不同角度。
        camera.rotateY(360 * (interpolatedTime));
        // 設置根據interpolatedTime時間在X柚上旋轉不同角度
        camera.rotateX((360 * interpolatedTime));
        // 獲取Transformation參數的Matrix對象
        Matrix matrix = t.getMatrix();
        camera.getMatrix(matrix);
        matrix.preTranslate(-centerX, -centerY);
        matrix.postTranslate(centerX, centerY);
        camera.restore();
    }
}

 

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