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

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