Android动画主要分为三大类:View Animation   Drawable Animation      Property Animation

  • Drawable Animations对大多数人来说是三者中最容易理解的,其实它就是很多书籍中提到的逐帧动画。而Property Animation和View Animation是相对比较容易混淆的,下面先讲解二者的区别。
  • View Animation两个缺点:(1)View Animation一般只能修改组件(View Object)的部分属性,比如:scaling(大小)和rotation(旋转),但是无法修改组件的背景颜色。(2)View Animation使某个组件产生动画效果移动一段距离后,比如从屏幕左侧移动到右侧,其实整个过程是绘制出来的效果,该组件真正的位置依然保留在左侧,只有点击左侧位置才能触发该组件。所以想真正移动某组件,需要在动画结束后添加代码实现。
  • Property Animation则没有以上View Animation的两个限制,Property Animation可以修改任何对象(View Object 或者 non-view Object)的任何属性,比如大小,旋转,颜色。并且,移动后的组件,位置也回跟随着改变。

Android官网推荐使用Property Animation,但是View Animation也有其优点:使用方便简单,所以当View Animation能方便快速地解决需求时,选择它也是不错的选择。

1. View/Tweened Animations(过渡动画):该类Animations提供了旋转、移动、伸展和淡出等效果。

  Alpha——淡入淡出,Scale——缩放效果,Rotate——旋转,Translate——移动效果。

AnimationSet set = new AnimationSet(false);       // 第一步, 创建AnmiationSet对象
Animation animation = new AlphaAnimation(0,1);   // 控制渐变透明的动画效果    第二步,动画类型
animation.setDuration(500);                     // 动画时间毫秒数   第三步,动画执行时间
set.addAnimation(animation);                   // 第四步,加入动画集合   
animation = new TranslateAnimation(1, 13, 10, 50);  // ScaleAnimation 控制尺寸伸缩的动画效果   
animation.setDuration(300);  
set.addAnimation(animation);  
animation = new RotateAnimation(30,10);         // TranslateAnimation  控制画面平移的动画效果   
animation.setDuration(300);  
set.addAnimation(animation);  
animation = new ScaleAnimation(5,0,2,0);         // RotateAnimation  控制画面角度变化的动画效果   
animation.setDuration(300);  
set.addAnimation(animation);  
LayoutAnimationController controller = new LayoutAnimationController(set, 1);  
GridView gridView = (GridView) this.findViewById(R.id.gridview);  
gridView .setLayoutAnimation(controller);        // GridView 设置动画效果   第五步,设置给view
ListView listview= (ListView)this.findViewById(R.id.listview);         // 也可以View.startAnimation()开始执行
listview.setLayoutAnimation(controller);         // ListView 设置动画效果

2. Drawable/Frame-by-frame Animations(帧动画):

  这一类Animations可以创建一个Drawable序列,这些Drawable可以按照指定的时间间歇一个一个的显示,类似电影。使用方法:

  1)在drawable/anim目录下新建一个frame.xml文件

<?xml version="1.0" encoding="utf-8"?>  
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"  
    android:oneshot="false">  // oneshot 为true的话,此动画只会执行一次,如果为false则一直循环。
    <item android:drawable="@drawable/f1" android:duration="300" />  
    <item android:drawable="@drawable/f2" android:duration="300" />  
    <item android:drawable="@drawable/f3" android:duration="300" />  
    <item android:drawable="@drawable/f4" android:duration="300" />  
</animation-list>

  我们可以将frame.xml文件放置于drawableanim目录,官方文档上是放到了drawable中了,大家可以根据喜好来放置,放在这两个目录都是可以运行的。

  2)执行动画命令:

     image.setBackgroundResource(R.anim.frame);  
        AnimationDrawable anim = (AnimationDrawable) image.getBackground();  
        anim.start();  

3. Property Animations(属性动画):

  Property Animation 是Android3.0(level 11)引入的一个款功能强大、灵活、健壮的动画系统,它可以为任何包括View在内的对象添加动画效果。就实现原理来分析,Property Aniamtion和Tween Animation之间最大的区别就是前者在为对象添加动画效果时,其更改的是对象的实际属性,而后者改变的只是View的绘制效果,View的实际属性值是不发生改变的。会用到的监听器和接口如下

Animator.AnimatorListener

    onAnimationStart()   —— 动画开始时调用;           onAnimationEnd()   —— 动画结束时调用;

    onAnimationRepeat() —— 动画循环播放时调用;     onAnimationCancel() —— 动画被取消时调用。

Animator.AnimatorUpdateListener

    onAnimationUpdate() —— 动画每播放一帧时调用。

   在动画过程中,可侦听此事件来获取并使用 ValueAnimator 计算出来的属性值。利用传入事件的 ValueAnimator 对象,调用其 getAnimatedValue() 方法即可获取当前的属性值。如果使用 ValueAnimator来实现动画的话 ,则必需实现此侦听器。

使用ValueAnimator实现动画的步骤及实践

1. 调用ValueAnimation类中的ofInt(int...values)、ofFloat(String propertyName,float...values)等静态方法实例化ValueAnimator对象,并设置目标属性的属性名、初始值或结束值等值;

2. 调用addUpdateListener(AnimatorUpdateListener mListener)方法为ValueAnimator对象设置属性变化的监听器;

3. 调用setInterpolator(TimeInterpolator value)为ValueAniamtor设置自定义的Interpolator(插值器,定义了动画变化过程中的属性变化规则);  (可选)

4. 调用setEvaluator(TypeEvaluator value)为ValueAnimator设置自定义的TypeEvaluator(估值器,告诉动画系统如何从初始值过度到结束值);  (可选)

5. 在AnimatorUpdateListener 中的实现方法为目标对象的属性设置计算好的属性值。

6. 设置动画的持续时间、是否重复及重复次数等属性;

7. 为ValueAnimator设置目标对象并开始执行动画。

/** 使用ValueAnimator实现图片缩放动画 */  
public void scaleValueAnimator(){  
//1.设置目标属性名及属性变化的初始值和结束值  
PropertyValuesHolder mPropertyValuesHolderScaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f,0.0f);  
PropertyValuesHolder mPropertyValuesHolderScaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f,0.0f);  
ValueAnimator mAnimator = ValueAnimator.ofPropertyValuesHolder(mPropertyValuesHolderScaleX,mPropertyValuesHolderScaleY);  
//2.为目标对象的属性变化设置监听器  
mAnimator.addUpdateListener(new AnimatorUpdateListener() {  
    public void onAnimationUpdate(ValueAnimator animation) {  
        // 3.根据属性名获取属性变化的值分别为ImageView目标对象设置X和Y轴的缩放值  
        float animatorValueScaleX =  (float) animation.getAnimatedValue("scaleX");  
        float animatorValueScaleY = (float) animation.getAnimatedValue("scaleY");  
        mImageViewTest.setScaleX(animatorValueScaleX);  
        mImageViewTest.setScaleY(animatorValueScaleY);  
}  
});  
//4.为ValueAnimator设置自定义的Interpolator  
mAnimator.setInterpolator(new CustomInterpolator());  
//5.设置动画的持续时间、是否重复及重复次数等属性  
mAnimator.setDuration(2000);  mAnimator.setRepeatCount(3);  
mAnimator.setRepeatMode(ValueAnimator.REVERSE);  
//6.为ValueAnimator设置目标对象并开始执行动画  
mAnimator.setTarget(mImageViewTest);  
mAnimator.start();  
}

  上面代码列表中,我们通过PropertyValuesHolder类为目标属性名来设置属性值的初始值和结束值,然后ValueAnimator通过调用ofPropertyValuesHolder(PropertyValuesHolder...values)设置已经配置好的PropertyValuesHolder对象。不过需要注意的是使用PropertyValuesHolder设置的属性必须是目标对象的属性中有setXX()方法才能进行设置,例如ImageView对象中有setScaleX()方法才能为ImageView设置对应属性的PropertyValuesHolder对象。接着ValueAnimator对象调用setInterpolator(TimeInterpolator value)设置自定义的Interpolator,类名为CustomInterpolator,具体的代码如下:

public class CustomInterpolator implements TimeInterpolator {  
    public float getInterpolation(float input) {  
        input *= 0.8f;  
        return input * input;  
    }  
}  

接着,为ValueAnimator对象设置相应的属性,如动画重复次数、动画所持续的时间等等。最后,为ValueAnimator设置目标对象并启动动画。

  另外还有一个,ObjectAnimator类,作为ValueAnimator的子类,不仅继承了它的所有方法和特性,并且还封装很多实用的方法,方便开发人员快速实现动画。同时,由于属性值会自动更新,使用ObjectAnimator实现动画不需要像ValueAnimator那样必须实现 ValueAnimator.AnimatorUpdateListener ,因此实现任意对象的动画显示就更加容易了。我们在大部分的开发工作中,都会使用ObjectAnimator而非ValueAnimator实现我们所需的动画效果。

ObjectAnimator实现动画的几个步骤,如下:

  首先,通过调用ofFloat()、ofInt()等方法创建ObjectAnimator对象,并设置目标对象、需要改变的目标属性名、初始值和结束值;然后,设置动画的持续时间、是否重复及重复次数等属性;最后,启动动画,就完成了。

使用ObjectAnimator实现动画也有一些要求和限制,一般有以下几点需要注意:

1.动画显示的属性必须带有一个 setter 方法,因为 ObjectAnimator 会在动画期间自动更新属性值,它必须能够用此 setter 方法访问到该属性。 例如:假设属性名称为foo,则需要有一个setFoo()方法。 而你如果此 setter 方法不存在,那么我们可以有以下三种选择:<1>如果权限允许的话,直接在类中增加此 setter 方法;<2>修改封装类来增加此 setter 方法,并让该封装类来接收属性值并传给初始的对象;<3>换用 ValueAnimator。

2.如果在调用 ObjectAnimator 的某个工厂方法时,我们只为 values... 参数指定了一个值,那此值将被认定为动画属性的结束值。 这样的话,动画显示的属性必须带有一个 getter 方法,用于获取动画的起始值。 此 getter 方法必须以get<propertyName>()的格式命名。 例如:假设属性名为foo,则需要有一个getFoo()方法。

3.动画属性的 getter 方法和 setter 方法所操作数据的类型必须与 ObjectAnimator 中设定的起始和结束值相同