Android動畫機制二----------補間動畫(Tween Animation)

補間動畫:指的是開發者無需定義動畫過程的每一幀,只需要定義動畫的開發和結束這兩個關鍵幀,並指定動畫變化的時間和方式等,然後交由Android系統進行計算,通過在兩個關鍵幀之間插入漸變值來實現平滑過渡,從而對View的內容完成一系列的圖形變換來實現的動畫效果

包含四種基本效果:透明度變化Alpha、大小變化Scale、位移變化Translate以及旋轉變化Rotate,這四種動畫任意組合實現複雜動畫,四種動畫的詳細功能如下表:


因爲補間動畫要用到插值器(Interpolator)先理解一下插值器是個什麼東西

在補間動畫中我們只要定義只要定義開始和結束的關鍵幀就可以完成動畫,中間的插入漸變值依據的便是插值器(interpolator),它繼承自TimeInterpolator(時間插值器),其允許動畫進行非線性的運動變化,如加速和減速等,接口中只有float getInterpolation(float input)這個方法,input應傳入一個0.0~1.0的值,返回值可以小於0.0也可以大於1.0

SDK默認提供了幾種插值器,如下表:


除了系統默認的插值器外,我們還可以自己定義插值器,只需實現Interpolator接口就可以。

補間動畫也可以有兩種實現方式,XML方式和代碼方式,下面分別介紹四種補間動畫及其實現方式

AlphaAnimation

AlphaAnimation的構造函數只有兩個參數:初始透明度,結束透明度,構造函數如下:

/**
     * Constructor to use when building an AlphaAnimation from code
     * 
     * @param fromAlpha Starting alpha value for the animation, where 1.0 means
     *        fully opaque and 0.0 means fully transparent.
     * @param toAlpha Ending alpha value for the animation.
     */
    public AlphaAnimation(float fromAlpha, float toAlpha) {
        mFromAlpha = fromAlpha;
        mToAlpha = toAlpha;
    }

XML方式就是在res/anim目錄中新建XML動畫,代碼如下:

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

    <!--1.0表示完全不透明   0.0表示完全透明 -->
    <alpha
        android:duration="10000"
        android:fromAlpha="1.0"
        android:toAlpha="0.0">
    </alpha>

</set>

使用方法如下:

Animation animation = AnimationUtils.loadAnimation(this,R.anim.test_alpha);
TweenAnim_Alpha_tv.setAnimation(animation);

代碼方式,代碼如下:

Animation animation = new AlphaAnimation(1f,0f);
animation.setDuration(10000);//時間爲10秒
animation.setFillAfter(true);//動畫結束時保留結束時的狀態
TweenAnim_Alpha_tv.setAnimation(animation);

ScaleAnimation

ScaleAnimation動畫的構造函數有3個,代碼如下:

 /**
     * Constructor to use when building a ScaleAnimation from code
     * 
     * @param fromX Horizontal scaling factor to apply at the start of the
     *        animation
     * @param toX Horizontal scaling factor to apply at the end of the animation
     * @param fromY Vertical scaling factor to apply at the start of the
     *        animation
     * @param toY Vertical scaling factor to apply at the end of the animation
     */
    public ScaleAnimation(float fromX, float toX, float fromY, float toY) {
        mResources = null;
        mFromX = fromX;
        mToX = toX;
        mFromY = fromY;
        mToY = toY;
        mPivotX = 0;
        mPivotY = 0;
    }

    /**
     * Constructor to use when building a ScaleAnimation from code
     * 
     * @param fromX Horizontal scaling factor to apply at the start of the
     *        animation
     * @param toX Horizontal scaling factor to apply at the end of the animation
     * @param fromY Vertical scaling factor to apply at the start of the
     *        animation
     * @param toY Vertical scaling factor to apply at the end of the animation
     * @param pivotX The X coordinate of the point about which the object is
     *        being scaled, specified as an absolute number where 0 is the left
     *        edge. (This point remains fixed while the object changes size.)
     * @param pivotY The Y coordinate of the point about which the object is
     *        being scaled, specified as an absolute number where 0 is the top
     *        edge. (This point remains fixed while the object changes size.)
     */
    public ScaleAnimation(float fromX, float toX, float fromY, float toY,
            float pivotX, float pivotY) {
        mResources = null;
        mFromX = fromX;
        mToX = toX;
        mFromY = fromY;
        mToY = toY;

        mPivotXType = ABSOLUTE;
        mPivotYType = ABSOLUTE;
        mPivotXValue = pivotX;
        mPivotYValue = pivotY;
        initializePivotPoint();
    }

    /**
     * Constructor to use when building a ScaleAnimation from code
     * 
     * @param fromX Horizontal scaling factor to apply at the start of the
     *        animation
     * @param toX Horizontal scaling factor to apply at the end of the animation
     * @param fromY Vertical scaling factor to apply at the start of the
     *        animation
     * @param toY Vertical scaling factor to apply at the end of the animation
     * @param pivotXType Specifies how pivotXValue should be interpreted. One of
     *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
     *        Animation.RELATIVE_TO_PARENT.
     * @param pivotXValue The X coordinate of the point about which the object
     *        is being scaled, specified as an absolute number where 0 is the
     *        left edge. (This point remains fixed while the object changes
     *        size.) This value can either be an absolute number if pivotXType
     *        is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
     * @param pivotYType Specifies how pivotYValue should be interpreted. One of
     *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
     *        Animation.RELATIVE_TO_PARENT.
     * @param pivotYValue The Y coordinate of the point about which the object
     *        is being scaled, specified as an absolute number where 0 is the
     *        top edge. (This point remains fixed while the object changes
     *        size.) This value can either be an absolute number if pivotYType
     *        is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
     */
    public ScaleAnimation(float fromX, float toX, float fromY, float toY,
            int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {
        mResources = null;
        mFromX = fromX;
        mToX = toX;
        mFromY = fromY;
        mToY = toY;

        mPivotXValue = pivotXValue;
        mPivotXType = pivotXType;
        mPivotYValue = pivotYValue;
        mPivotYType = pivotYType;
        initializePivotPoint();
    }

可以看到涉及到參數較多,具體含義如下表:


XML的實現方式如下:

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

    <scale
        android:duration="5000"
        android:fromXScale="0.2"
        android:fromYScale="0.2"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1"
        android:toYScale="1"
        ></scale>
    
</set>

使用方法如下:

Animation animation = AnimationUtils.loadAnimation(this,R.anim.test_scale);
TweenAnim_Scale_tv.setAnimation(animation);

代碼實現方式如下:

Animation animation = new ScaleAnimation(
                1.0f,4.0f,
                1.0f,4.0f,
                Animation.RELATIVE_TO_SELF,0.0f,
                Animation.RELATIVE_TO_SELF,0.0f);
        animation.setDuration(10000);
        animation.setFillAfter(true);
        TweenAnim_Scale_tv.setAnimation(animation);

TranslateAnimation

其構造函數有兩個,代碼如下:

 /**
     * Constructor to use when building a TranslateAnimation from code
     *
     * @param fromXDelta Change in X coordinate to apply at the start of the
     *        animation
     * @param toXDelta Change in X coordinate to apply at the end of the
     *        animation
     * @param fromYDelta Change in Y coordinate to apply at the start of the
     *        animation
     * @param toYDelta Change in Y coordinate to apply at the end of the
     *        animation
     */
    public TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) {
        mFromXValue = fromXDelta;
        mToXValue = toXDelta;
        mFromYValue = fromYDelta;
        mToYValue = toYDelta;

        mFromXType = ABSOLUTE;
        mToXType = ABSOLUTE;
        mFromYType = ABSOLUTE;
        mToYType = ABSOLUTE;
    }

    /**
     * Constructor to use when building a TranslateAnimation from code
     * 
     * @param fromXType Specifies how fromXValue should be interpreted. One of
     *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
     *        Animation.RELATIVE_TO_PARENT.
     * @param fromXValue Change in X coordinate to apply at the start of the
     *        animation. This value can either be an absolute number if fromXType
     *        is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
     * @param toXType Specifies how toXValue should be interpreted. One of
     *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
     *        Animation.RELATIVE_TO_PARENT.
     * @param toXValue Change in X coordinate to apply at the end of the
     *        animation. This value can either be an absolute number if toXType
     *        is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
     * @param fromYType Specifies how fromYValue should be interpreted. One of
     *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
     *        Animation.RELATIVE_TO_PARENT.
     * @param fromYValue Change in Y coordinate to apply at the start of the
     *        animation. This value can either be an absolute number if fromYType
     *        is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
     * @param toYType Specifies how toYValue should be interpreted. One of
     *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
     *        Animation.RELATIVE_TO_PARENT.
     * @param toYValue Change in Y coordinate to apply at the end of the
     *        animation. This value can either be an absolute number if toYType
     *        is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
     */
    public TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,
            int fromYType, float fromYValue, int toYType, float toYValue) {

        mFromXValue = fromXValue;
        mToXValue = toXValue;
        mFromYValue = fromYValue;
        mToYValue = toYValue;

        mFromXType = fromXType;
        mToXType = toXType;
        mFromYType = fromYType;
        mToYType = toYType;
    }

具體參數的含義如下:


TranslateAnimation動畫的具體實現方式:

XML方式的XML代碼如下:

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

    <translate
        android:duration="10000"
        android:fromXDelta="200"
        android:toXDelta="0"
        android:fromYDelta="100"
        android:toYDelta="100"></translate>

</set>

使用方法如下:

Animation animation = AnimationUtils.loadAnimation(this,R.anim.test_translate);
TweenAnim_Translate_tv.setAnimation(animation);

代碼方式如下:

Animation animation = new TranslateAnimation(
                Animation.RELATIVE_TO_SELF,0.0f,
                Animation.RELATIVE_TO_SELF,2.0f,
                Animation.RELATIVE_TO_SELF,0.0f,
                Animation.RELATIVE_TO_SELF,2.0f);
        animation.setFillAfter(true);
        animation.setDuration(10000);
        TweenAnim_Translate_tv.setAnimation(animation);

RotateAnimation

其構造函數有3個,代碼如下:

 /**
     * Constructor to use when building a RotateAnimation from code.
     * Default pivotX/pivotY point is (0,0).
     * 
     * @param fromDegrees Rotation offset to apply at the start of the
     *        animation.
     * 
     * @param toDegrees Rotation offset to apply at the end of the animation.
     */
    public RotateAnimation(float fromDegrees, float toDegrees) {
        mFromDegrees = fromDegrees;
        mToDegrees = toDegrees;
        mPivotX = 0.0f;
        mPivotY = 0.0f;
    }

    /**
     * Constructor to use when building a RotateAnimation from code
     * 
     * @param fromDegrees Rotation offset to apply at the start of the
     *        animation.
     * 
     * @param toDegrees Rotation offset to apply at the end of the animation.
     * 
     * @param pivotX The X coordinate of the point about which the object is
     *        being rotated, specified as an absolute number where 0 is the left
     *        edge.
     * @param pivotY The Y coordinate of the point about which the object is
     *        being rotated, specified as an absolute number where 0 is the top
     *        edge.
     */
    public RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY) {
        mFromDegrees = fromDegrees;
        mToDegrees = toDegrees;

        mPivotXType = ABSOLUTE;
        mPivotYType = ABSOLUTE;
        mPivotXValue = pivotX;
        mPivotYValue = pivotY;
        initializePivotPoint();
    }

    /**
     * Constructor to use when building a RotateAnimation from code
     * 
     * @param fromDegrees Rotation offset to apply at the start of the
     *        animation.
     * 
     * @param toDegrees Rotation offset to apply at the end of the animation.
     * 
     * @param pivotXType Specifies how pivotXValue should be interpreted. One of
     *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
     *        Animation.RELATIVE_TO_PARENT.
     * @param pivotXValue The X coordinate of the point about which the object
     *        is being rotated, specified as an absolute number where 0 is the
     *        left edge. This value can either be an absolute number if
     *        pivotXType is ABSOLUTE, or a percentage (where 1.0 is 100%)
     *        otherwise.
     * @param pivotYType Specifies how pivotYValue should be interpreted. One of
     *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
     *        Animation.RELATIVE_TO_PARENT.
     * @param pivotYValue The Y coordinate of the point about which the object
     *        is being rotated, specified as an absolute number where 0 is the
     *        top edge. This value can either be an absolute number if
     *        pivotYType is ABSOLUTE, or a percentage (where 1.0 is 100%)
     *        otherwise.
     */
    public RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,
            int pivotYType, float pivotYValue) {
        mFromDegrees = fromDegrees;
        mToDegrees = toDegrees;

        mPivotXValue = pivotXValue;
        mPivotXType = pivotXType;
        mPivotYValue = pivotYValue;
        mPivotYType = pivotYType;
        initializePivotPoint();
    }

各個參數代表的意義如下表:


RotateAnimation動畫的實現方式

XML方式的代碼如下:

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

    <rotate
        android:duration="10000"
        android:fromDegrees="0"
        android:pivotY="50%"
        android:pivotX="50%"
        android:startOffset="0"
        android:repeatCount="-1"
        android:repeatMode="restart"
        android:toDegrees="360"></rotate>

</set>

使用方法:

Animation animation = new RotateAnimation(
                0,-720,
                Animation.RELATIVE_TO_SELF,0.5f,
                Animation.RELATIVE_TO_SELF,0.5f);
        animation.setDuration(10000);
        animation.setFillAfter(true);
        TweenAnim_Rotate_tv.setAnimation(animation);

自定義補間動畫

在實際的項目中,往往出現比較複雜的動畫需求,則需要自定義補間動畫來實現,只需要繼承Animation,然後重寫applyTransformation(float interpolatedTime,Transformation)方法

interpolatedTime:代表了動畫的時間進行比

Tansformation:該參數代表了初間動畫在不同時刻對圖形或組件的變形程度,其中封裝了一個Matrix對象

爲了控制圖片或View進行三維的變換,還需要藉助Android提供的Camera.手機的三維座標系統有x,y,z三個軸Camera對象提供了相應補間動畫的X,Y,Z三個方向的對應操作方法

下面給出一個自定義補間動畫的例子:

public class MyTweenAnimation extends Animation
{
    private int centerX;
    private int centerY;
    //定義動畫的持續事件  
    private int duration;
    private Camera camera = new Camera();
    public MyTweenAnimation(int centerX, int centerY , int duration)
    {
        this.centerX = centerX;
        this.centerY = centerY;
        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();
    }
}  

自定義補間動畫的使用:

myTweenAnimation = new MyTweenAnimation(Animation.RELATIVE_TO_SELF,Animation.RELATIVE_TO_SELF,5000);
myTweenAnimation.setRepeatCount(-1);//一直重複
TweenAnim_MySelfAnimation_tv.setAnimation(myTweenAnimation);

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