Android Tween Animation動畫效果詳解

Android動畫分類:

1.補間動畫 Tween Animation
2.逐幀動畫 Frame Animation
3. 屬性動畫 Property Animation

下面我們來講的就是補間動畫:

1.AlphaAnimation 透明動畫

代碼:

    /**
     * 透明度動畫
     *
     * @param view
     */
    private void alphaAnimation(View view) {
        //初始化動畫,參數  1.動畫開始透明度 2.動畫結束透明度
        AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
        //動畫持續時間 Animation類的方法,AlphaAnimation繼承自Animation類
        alphaAnimation.setDuration(1000);
        //是否停留在最後一幀
        alphaAnimation.setFillAfter(true);
        //設置重複次數
        alphaAnimation.setRepeatCount(3);
        //執行前的等待時間
        alphaAnimation.setStartOffset(100);
        //開啓執行動畫
        view.startAnimation(alphaAnimation);

        //如果想在動畫開始,結束,重複的時候進行一些操作,可以設置動畫事件的監聽
        alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                //動畫開始的時候調用
                Log.d("測試", "onAnimationStart");
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                //動畫結束的時候調用
                Log.d("測試", "onAnimationEnd");
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
                //動畫重複執行的時候調用
                Log.d("測試", "onAnimationRepeat");
            }
        });

    }

使用xml文件來配置動畫效果:
在res文件夾下新建anim文件夾,這個就是用來放置xml動畫文件的文件夾,下面新建test_alpha.xml文件配置文件內容

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

如何調用:

 view.startAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.test_alpha));

效果:

2.RotateAnimation 旋轉動畫
    /**
     * 旋轉動畫
     *
     * @param view
     */
    private void rotateAnimation(View view) {
        //初始化參數 1.開始角度 2.結束角度 3.旋轉中心點x軸座標 4.旋轉中心點y軸座標
        RotateAnimation rotateAnimation = new RotateAnimation(0, 360, view.getWidth() / 2, view.getHeight() / 2);
        rotateAnimation.setDuration(1000);
        view.startAnimation(rotateAnimation);
    }

xml:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="360">
    <!--pivotX 旋轉中心的x座標    50%即是相對於其自身寬度的50%
     pivotY 旋轉中心的y座標
     fromDegrees 開始角度
    toDegrees 結束角度  -->

</rotate>

效果:

3.TranslateAnimation 位移動畫
    /**
     * 位移動畫
     *
     * @param view
     */
    private void translateAnimation(View view) {
        //參數1.開始x軸位置  2.移動到x軸的位置 3.開始的y軸位置 4.移動到y軸的位置
        TranslateAnimation translateAnimation = new TranslateAnimation(view.getWidth(), view.getWidth(), 0, view.getHeight());
        translateAnimation.setDuration(1000);
        translateAnimation.setFillAfter(true);
        view.startAnimation(translateAnimation);
    }

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:duration="1000"
    android:toXDelta="100%"
    android:toYDelta="100%">

</translate>

效果:

4.ScaleAnimation 縮放動畫
    /**
     * 縮放動畫
     *
     * @param view
     */
    private void scaleAnimation(View view) {
        //1.從x軸的縮放比例 2.到x軸的縮放比例 3.從y軸的縮放比例 4.到y軸的縮放比例 5.縮放中心點的x座標 6.縮放中心點的y座標
        ScaleAnimation scaleAnimation = new ScaleAnimation(0, 1, 0, 1, view.getWidth() / 2, view.getHeight() / 2);
        scaleAnimation.setDuration(1000);
        view.startAnimation(scaleAnimation);
    }

xml:

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

</scale>

效果:

5.AnimationSet 動畫集合
    /**
     * 混合動畫
     *
     * @param v
     */
    private void animationSet(View v) {
        //獲取屏幕寬度
        WindowManager wm = getWindowManager();
        int width = wm.getDefaultDisplay().getWidth();

        //1.是否共用插值器
        AnimationSet animationSet = new AnimationSet(true);

        //位移
        TranslateAnimation translateAnimation = new TranslateAnimation(0, width / 2 - v.getWidth() / 2, 0, 0);
        translateAnimation.setDuration(0);
        animationSet.addAnimation(translateAnimation);

        //縮放
        ScaleAnimation scaleAnimation = new ScaleAnimation(0, 3, 0, 3, width / 2, v.getHeight() / 2);
        scaleAnimation.setDuration(3000);
        animationSet.addAnimation(scaleAnimation);

        //透明度
        AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
        alphaAnimation.setDuration(3000);
        animationSet.addAnimation(alphaAnimation);

        //旋轉
        RotateAnimation rotateAnimation = new RotateAnimation(0, 360, width / 2, v.getHeight() / 2);
        rotateAnimation.setDuration(3000);
        animationSet.addAnimation(rotateAnimation);
        v.startAnimation(animationSet);
    }

xml:

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


    <alpha
        android:fromAlpha="0"
        android:toAlpha="1"></alpha>

    <translate
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="100%"
        android:toYDelta="100%"></translate>
</set>

AnimationSet就是一個動畫集合將所有東西糅合在一起執行
效果:

6.關於自定義動畫:

在寫自定義動畫之前,先來看看AlphaAnimation類的源碼:

/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.view.animation;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;

/**
 * An animation that controls the alpha level of an object.
 * Useful for fading things in and out. This animation ends up
 * changing the alpha property of a {@link Transformation}
 *
 */
public class AlphaAnimation extends Animation {
    private float mFromAlpha;
    private float mToAlpha;

    /**
     * Constructor used when an AlphaAnimation is loaded from a resource. 
     * 
     * @param context Application context to use
     * @param attrs Attribute set from which to read values
     */
    public AlphaAnimation(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray a =
            context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.AlphaAnimation);

        mFromAlpha = a.getFloat(com.android.internal.R.styleable.AlphaAnimation_fromAlpha, 1.0f);
        mToAlpha = a.getFloat(com.android.internal.R.styleable.AlphaAnimation_toAlpha, 1.0f);

        a.recycle();
    }

    /**
     * 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;
    }

    /**
     * Changes the alpha property of the supplied {@link Transformation}
     */
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        final float alpha = mFromAlpha;
        t.setAlpha(alpha + ((mToAlpha - alpha) * interpolatedTime));
    }

    @Override
    public boolean willChangeTransformationMatrix() {
        return false;
    }

    @Override
    public boolean willChangeBounds() {
        return false;
    }

    /**
     * @hide
     */
    @Override
    public boolean hasAlpha() {
        return true;
    }
}

發現AlphaAnimation繼承自Animation類,所重寫的方法有:

1.applyTransformation
這個方法會被父類不斷的調用,其中有兩個參數
a.float interpolatedTime 這個參數會在動畫的執行過程中不斷的變化,從開始的時候爲0,一直到結束的時候爲1
b.Transformation t 這個類中封裝了一些屬性供子類調用
來看下其具體代碼:

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        final float alpha = mFromAlpha;
        t.setAlpha(alpha + ((mToAlpha - alpha) * interpolatedTime));
    }

代碼很簡單通過t.setAlpha()這個方法去改變控件的alpha屬性,然後通過一次次的調用來達到動畫的效果

2.willChangeTransformationMatrix
這個方法大概的意思就是該動畫是否會改變Matrix矩陣,父類Animaction默認返回true,因爲AlphaAnimation只是對透明度的改變不會改變Matrix,所以返回false
3.willChangeBounds
這個方法的意思是動畫是否影響指定的視圖範圍,父類Animaction默認返回true,同理AlphaAnimation返回false
4.hasAlpha
是否有透明度的變化,Animaction默認返回false

AlphaAnimation類除了構造方法之外就這有那麼多東西

在來看看RotateAnimation類:

/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.view.animation;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;

/**
 * An animation that controls the rotation of an object. This rotation takes
 * place in the X-Y plane. You can specify the point to use for the center of
 * the rotation, where (0,0) is the top left point. If not specified, (0,0) is
 * the default rotation point.
 * 
 */
public class RotateAnimation extends Animation {
    private float mFromDegrees;
    private float mToDegrees;

    private int mPivotXType = ABSOLUTE;
    private int mPivotYType = ABSOLUTE;
    private float mPivotXValue = 0.0f;
    private float mPivotYValue = 0.0f;

    private float mPivotX;
    private float mPivotY;

    /**
     * Constructor used when a RotateAnimation is loaded from a resource.
     * 
     * @param context Application context to use
     * @param attrs Attribute set from which to read values
     */
    public RotateAnimation(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray a = context.obtainStyledAttributes(attrs,
                com.android.internal.R.styleable.RotateAnimation);

        mFromDegrees = a.getFloat(
                com.android.internal.R.styleable.RotateAnimation_fromDegrees, 0.0f);
        mToDegrees = a.getFloat(com.android.internal.R.styleable.RotateAnimation_toDegrees, 0.0f);

        Description d = Description.parseValue(a.peekValue(
            com.android.internal.R.styleable.RotateAnimation_pivotX));
        mPivotXType = d.type;
        mPivotXValue = d.value;

        d = Description.parseValue(a.peekValue(
            com.android.internal.R.styleable.RotateAnimation_pivotY));
        mPivotYType = d.type;
        mPivotYValue = d.value;

        a.recycle();

        initializePivotPoint();
    }

    /**
     * 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();
    }

    /**
     * Called at the end of constructor methods to initialize, if possible, values for
     * the pivot point. This is only possible for ABSOLUTE pivot values.
     */
    private void initializePivotPoint() {
        if (mPivotXType == ABSOLUTE) {
            mPivotX = mPivotXValue;
        }
        if (mPivotYType == ABSOLUTE) {
            mPivotY = mPivotYValue;
        }
    }

    @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);
        }
    }

    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
        mPivotX = resolveSize(mPivotXType, mPivotXValue, width, parentWidth);
        mPivotY = resolveSize(mPivotYType, mPivotYValue, height, parentHeight);
    }
}

一看到除了構造方法外重寫的父類的方法又多了一個initialize();只看方法名也看的出來這是一個初始化的方法,在動畫開始之前會調用這個方法,其中傳遞過來的參數分別是,動畫目標對象的寬高以及其父對象的寬高,然後在applyTransformation中通過t.getMatrix()獲取到矩陣,去執行旋轉的方法。

至於其他的ScaleAnimation和TranslateAnimation也都是重寫了initialize()和applyTransformation()通過Matrix矩陣來不斷的修改屬性來達到動畫的效果

只要明白了這個,那麼再來寫自定義動畫就簡單多了
下面我們來寫一個拉伸的動畫效果:
代碼:

package wkk.app12;

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

/**
 * Created by wkk on 2016/11/8.
 */
public class Animation_m extends Animation {

    private int height;

    //動畫執行之前調用此方法,分別是目標對象以及其父容器的寬高
    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
        this.height = height;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        //1.補間 從0至1     本方法將會在動畫執行期間不斷調用
        //x軸 y軸   中心點x軸 y軸
        t.getMatrix().setSkew((float) Math.sin(interpolatedTime * 6), 0, 0, height);
    }
}

效果:

ps:
起個什麼什麼詳解的名字感覺自己也變成了大神一樣,哈哈哈…


2016/11/15 11:07
demo下載地址:
http://download.csdn.net/detail/w18756901575/9676302

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