最近在学习《Android开发艺术探索》这本书,并且对第七章作了一个学习总结,以便自己加深印象。Android动画分为View动画、帧动画、属性动画。严格来讲,帧动画也属于View动画,只是它和常见的View动画在表现形式不一样而已View动画属于对各种场景对象做图像变换从而产生动画效果,属于渐进式动画,且支持自定义;帧动画是按一定顺序播放一系列图像产生的动画效果,可以理解为图片切换效果,尤其明显的缺点是图片过多过大会导致OOM。属性动画是动态的修改对象的属性从而达到动画的效果。这里分为两部分来讲:

一、View动画(包含了帧动画);
二、属性动画;

首先,View动画分为平移动画、缩放动画、旋转动画、透明动画四种表现形式:

名称      标签          子类                  描述
            平移动画    <translate>     TranslateAnimation      移动View
            缩放动画    <scale>         ScaleAnimation          放大或者缩小View
            旋转动画    <rotate>        RotateAnimation         旋转View
            透明度动画   <alpha>         AlphaAnimation          改变View的透明度

xml编写动画,xml文件放置于anim文件下面:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="true"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:zAdjustment="normal">
   <!--
    android:interpolator为动画集合指定插值器,配合android:shareInterpolator使用;
    android:shareInterpolator决定动画集合的动画是否共享同一个插值器

    android:zAdjustment="normal"
    normal(0):正在播放的动画内容保持当前的Z轴顺序,
    top(1):在动画播放期间,强制把当前播放的内容放到其他内容的上面;
    bottom(-1):在动画播放期间,强制把当前播放的内容放到其他内容之下
    -->
    <rotate

        android:fromDegrees="90"
        android:toDegrees="270"
        android:duration="1000"
        android:fillAfter="false">

        <!--
    android:fromDegrees="90"  起始角度
    android:toDegrees="270"   结束角度
    android:duration="1000"   动画时间
    android:fillAfter="false" 动画结束以后View显示位置是否停留在结束位置
    -->
    </rotate>


    <alpha
        android:fromAlpha="0.1"
        android:toAlpha="1"
        android:duration="1000"
        android:fillAfter="false">

        <!--
        android:fromAlpha="0.1"     开始的透明度
        android:toAlpha="1"         结束的透明度
        -->
    </alpha>
    <scale
        android:fromXScale="0.5"
        android:toXScale="1.5"
        android:fromYScale="0.5"
        android:toYScale="1.5"
        android:duration="1000"
        android:fillAfter="false">

        <!--
        android:fromXScale="0.5"    X轴开始缩放的起始值;
        android:toXScale="1.5"      X轴结束缩放的结束值
        android:fromYScale="0.5"    Y轴开始缩放的起始值;
        android:toYScale="1.5"      Y轴结束缩放的结束值
        -->
    </scale>

    <translate
        android:fromXDelta="100"
        android:toXDelta="200"
        android:fromYDelta="0"
        android:toYDelta="0"
        android:duration="1000"
        android:fillAfter="false"
        >

        <!--
        android:fromXDelta="100"    X方向平移的起点位置
        android:toXDelta="200"      X方向平移的终点位置
        android:fromYDelta="0"      Y方向平移的起点位置
        android:toYDelta="0"        Y方向平移的终点位置
        -->

    </translate>
</set>

使用:

Animation animation = AnimationUtils.loadAnimation(this,R.anim.translate);
        btnDemo.startAnimation(animation);

直接使用代码:

TranslateAnimation translateAnimation = new TranslateAnimation(100,200,0,0);
//        public TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
//        该方法参数同xml里面一致
        translateAnimation.setDuration(1000);
        translateAnimation.setFillAfter(false);
        btnDemo.startAnimation(translateAnimation);

上面都是原生的动画,各位要是觉得不满意,还可以自定义View动画,不过现在很少使用,自己还可以自定义一个,下面是Android ApiDemos的一个自定义View动画,动画效果大家可以自己看demo:

package vicent.softb.hhqy.com.animationdemo;

import android.graphics.Camera;
import android.graphics.Matrix;
import android.view.animation.Animation;
import android.view.animation.Transformation;

/**
 * Created by Administrator on 2016/8/25.
 */
public class Rotate3DAnimation extends Animation
{
    private final float mFromDegeees;
    private final float mToDegeees;
    private final float mCenterX;
    private final float mCenterY;
    private final float mDepthz;
    private final boolean mReverse;
    private Camera camera;

    public Rotate3DAnimation(float fromDegrees,float toDegrees,float centerX,float centerY,float depthz,boolean reverse)
    {
        mFromDegeees = fromDegrees;
        mToDegeees = toDegrees;
        mCenterX = centerX;
        mCenterY = centerY;
        mDepthz = depthz;
        mReverse = reverse;
    }

    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight)
    {
        super.initialize(width, height, parentWidth, parentHeight);
        camera = new Camera();
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t)
    {
        super.applyTransformation(interpolatedTime, t);
        final float fromDegrees = mFromDegeees;
        float degrees = fromDegrees+(mToDegeees-fromDegrees)*interpolatedTime;
        final float centerX = mCenterX;
        final float centerY = mCenterY;
        final Camera mcamera = camera;
        final Matrix matrix = t.getMatrix();
        mcamera.save();
        if(mReverse)
        {
            mcamera.translate(0,0,mDepthz*interpolatedTime);
        }
        else
        {
            mcamera.translate(0,0,mDepthz*(1-interpolatedTime));
        }
        mcamera.rotateY(degrees);
        mcamera.getMatrix(matrix);
        camera.restore();
        matrix.preTranslate(-centerX,-centerY);
        matrix.postTranslate(centerX,centerY);
    }
}

接着是帧动画,帧动画类似于gif图片,默认重复播放,很好理解也很好用,但是切忌避免使用过多尺寸和过大的图片,OOM啊!!
xml资源,记住这个是放在drawable文件夹下面的

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

    <item android:drawable="@mipmap/common_loading_0" android:duration="100"></item>
    <item android:drawable="@mipmap/common_loading_1" android:duration="100"></item>
    <item android:drawable="@mipmap/common_loading_2" android:duration="100"></item>
    <item android:drawable="@mipmap/common_loading_3" android:duration="100"></item>
    <item android:drawable="@mipmap/common_loading_4" android:duration="100"></item>
    <item android:drawable="@mipmap/common_loading_5" android:duration="100"></item>
    <item android:drawable="@mipmap/common_loading_6" android:duration="100"></item>
    <item android:drawable="@mipmap/common_loading_7" android:duration="100"></item>
    <item android:drawable="@mipmap/common_loading_8" android:duration="100"></item>
    <item android:drawable="@mipmap/common_loading_9" android:duration="100"></item>
    <item android:drawable="@mipmap/common_loading_10" android:duration="100"></item>
    <item android:drawable="@mipmap/common_loading_11" android:duration="100"></item>

</animation-list>
//对控件在布局的时候使用
android:background="@drawable/frame_animation"

资源布置好了就可以使用了,

AnimationDrawable aniamtionDrawable = (AnimationDrawable) btnDemo.getBackground();
        aniamtionDrawable.start();

接下来是动画的一些使用场景,除了四种形式(平移、旋转、缩放、透明)外,View动画还可以在特殊的场景下使用:

1、动画过程监听

private void startCustomViewAnimation()
    {
        Animation animation = new Rotate3DAnimation(90,270,btnDemo.getX(),btnDemo.getY(),20,false);
        animation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {

            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        btnDemo.startAnimation(animation);
    }

2、LayoutAnimation
LayoutAnimation作用于Viewgroup,为Viewgroup指定一个动画,它的子元素出场就会具有这种效果了。
xml布局文件放置于drawable下面的anim文件下:

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

<!--
    android:delay   子元素开始动画的延迟时间
    android:animationOrder  子元素动画的顺序
    normal      排在前面的子元素先开始播放入场动画;
    reverse     逆向显示,排在后面的子元素开始播放入场动画;
    random      随机播放入场动画
    -->
</layoutAnimation>

<!--  ------      -->
//使用方法
<android.support.v4.view.ViewPager
        android:id="@+id/id_viewPager"
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1"
        android:layoutAnimation="@anim/layout">

这样就可以做到自带动画了,不需要额外的java代码了,但是也可以直接使用java代码来完成这个动画,但是资源文件一样还是需要的,如下:

Animation animation = AnimationUtils.loadAnimation(this,R.anim.layout);
        LayoutAnimationController controller = new LayoutAnimationController(animation,0.5f);
        controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
//        通过查看源码,ViewPager没有该方法,但是Viewgroup却有该方法,所以只有部分Viewgroup的子类才能使用java代码来加载该动画
//        ViewPager.setLayoutAnimation(controller);
        ListView lv = new ListView(this);
        lv.setLayoutAnimation(controller);

3、Activity的动画切换效果
Activity有默认的切换效果,但是也可以自定义,代码如下:

//enterAnim代表Activity打开时的动画资源
//exitAnim代表Activity退出时的动画效果
public void overridePendingTransition(int enterAnim, int exitAnim)

该方法一般在startActivity方法之后调用,为Activity添加动画效果,也可以在finish方法之后调用,为自己定义退出的动画效果。

4、Fragment切换效果
这个动画效果有很多,但是这里简单说一个,说不定今后有特殊场景需要用到呢?

getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.alpha,R.anim.translate);

待续。。。。。。