属性动画详解(Animator)


1、概述

对于之前介绍的Animation,它属于视图动画(View Animation)(可参见:Animation 动画详解),包括补间动画(Tween Animation)和逐帧动画(Tween Animation);而在android中还有另一种动画,那就是属性动画(Property Animator),它包括ValueAnimatorObjectAnimator

两者的区别

  • 引入时间不同
    视图动画在API Level 1 引入的,而属性动画在API Level 11(即 android 3.0)引入的;
  • 所在包不同
    视图动画在 android.view.animation.Animation包下,属性动画在:android.animation包下
  • 动画类的命名不同
    视图动画中类的名字为:XXXAnimation,而在属性动画中是:XXXAnimator
  • 作用的对象不同(这个也是引入属性动画的原因)
    视图动画是对控件做动画,不能改变控件内部的属性,对所有的控件都可以;而属性动画是通过改变控件的属性来实现动画,但使用ObjectAnimator时要求作用的控件的属性要有get,set方法。如果控件的属性没有get/set方法,可以通过包装类间接的设置get/set方法,或者使用ValueAnimator 实现。

2、ValueAnimator 的基本使用

ValueAnimator是动画的核心,但不提供任何动画效果,它更像一个数值发生器,产生具有一定规律的数字,然后让调用者来控制动画的实现过程。用法如下:

  • 创建ValueAnimator实例
    例:创建0到500的动画,时间为1s:

    ValueAnimator animator = ValueAnimator.ofInt(0,500);  
    animator.setDuration(1000); 
    

    代码中可以看出,它不与任何控件关联,只对动画做运算。

  • 添加它的监听事件
    下面是给它添加监听事件,实现动画的。

    animator.addUpdateListener(new ValueAnimator.
                         AnimatorUpdateListener() {
                     @Override
                     public void onAnimationUpdate(ValueAnimator animation) {
                         //具体处理动画逻辑
                     }
                 });
                 //开启动画
                 animator.start();
    
    

    具体示例:
    点击按钮使textView从(200,200)移动到(600,,600)

    btnStartAnim = (Button) findViewById(R.id.btn);
    tv = (TextView) findViewById(R.id.tv);
    btnStartAnim.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View v) {
         //设置数据
         ValueAnimator animator = ValueAnimator.ofInt(200, 600);
         animator.setDuration(1000);
         //监听动画
         animator.addUpdateListener(new ValueAnimator.
                 AnimatorUpdateListener() {
             @Override
             public void onAnimationUpdate(ValueAnimator animation) {
                 //获取当前动画的值
                 int curValue = (int) animation.getAnimatedValue();
                 //设置tv的位置
                 tv.layout(curValue, curValue,
                         curValue + tv.getWidth(),
                         curValue + tv.getHeight());
             }
         });
         //开启动画
         animator.start();
     }
    });
    

    示例效果:

3、ValueAnimator 常用方法

/**
* 设置动画参数,参数类型为可变参数
*/
ValueAnimator ofInt(int... values);
ValueAnimator ofFloat(int... values);

/**
* 设置动画时长,单位是毫秒
*/
ValueAnimator setDuration(long duration);

/**
* 获取 ValueAnimator 在运动时,当前运动点的值
*/
Object getAnimatedValue();

/**
* 开始动画
*/
void start();

/**
* 设置循环次数,设置为 INFINITE 表示无限循环
*/
void setRepeatCount(int value);

/**
* 设置循环模式
* value 取值有 RESTART,REVERSE(分别为:重新开始,倒序重新开始)
*/
void setRepeatMode(int value);

/**
* 取消动画
*/
void cancel();

通过源码,发现ofInt和ofFloat方法内部实现一样的,他们的区别在于传入的参数类型不同,需要注意的是在使用getAnimatedValue方法时,如果前面使用的是ofInt,要强转成int 类型,否则,转为float类型。
此外,如果不需要动画,可以调用移除动画监听方法,但需要先调用cancel方法取消动画。

4、ObjectAnimator 的基本使用

ObjectAnimator 类继承自ValueAnimator,使用时通过静态工厂类直接返回一个对象,参数包括对象和对象的属性名,但该属性必须要有get和set函数,这样可以真实的控制一个view的属性值,因此它基本可以实现所有的动画效果。
使用示例:
使textView的translationX从0变化到200在变化到500,持续时间为1s,代码如下:

ObjectAnimator animator = ObjectAnimator.ofFloat(textView,
            "translationX",new float[]{200,500});
    animator.setDuration(1000);
    animator.start();

ofFloat的参数:第一个是要操纵的View;第二个是要操纵的属性;第三个是参数,是一个可变数组。同样的,可以给它设置显示时长,插值器等。
在开始提到了,ObjectAnimator用于有get,set属性的控件,对于没有的可以通过一个包装类来实现,如下:

/**
 * 包装类,给width添加get,set方法
 */
public static class WrapperView {
    private View mTarget;

    public WrapperView(View target) {
        mTarget = target;
    }

    public int getWidth() {
        return mTarget.getLayoutParams().width;
    }

    public void setWidth(int width) {
        mTarget.getLayoutParams().width = width;
        mTarget.requestLayout();
    }
}

使用时,直接操纵包装类,如下:

WrapperView mWrapperView = new WrapperView(btnStartAnim);
ObjectAnimator animator = ObjectAnimator.ofInt(
        mWrapperView,"width",500).setDuration(500);
animator.start();

通过上面,可以知道,ObjectAnimator 实现动画主要是通过set方法来设置控件的对应的属性实现动画。

5、ObjectAnimator 的常用方法

除了上面的ofInt,ofFloat方法,对于要改变背景色的,可以使用ArgbEvaluator,用法如下,给textView设置背景色在三种颜色间变化:

ObjectAnimator animator = ObjectAnimator.ofInt(textView,
        "BackgroundColor",0xffff00ff, 0xffffff00, 0xffff00ff);
animator.setDuration(2000);
animator.setEvaluator(new ArgbEvaluator());
animator.start();

其他常用函数如下:
摘抄于:http://wiki.jikexueyuan.com/project/android-animation/7.html

/** 
 * 设置动画时长,单位是毫秒 
 */  
ValueAnimator setDuration(long duration)  
/** 
 * 获取 ValueAnimator 在运动时,当前运动点的值 
 */  
Object getAnimatedValue();  
/** 
 * 开始动画 
 */  
void start()  
/** 
 * 设置循环次数,设置为 INFINITE 表示无限循环 
 */  
void setRepeatCount(int value)  
/** 
 * 设置循环模式 
 * value 取值有 RESTART,REVERSE, 
 */  
void setRepeatMode(int value)  
/** 
 * 取消动画 
 */  
void cancel() 

监听相关的方法:

/** 
 * 监听器一:监听动画变化时的实时值 
 */  
public static interface AnimatorUpdateListener {  
    void onAnimationUpdate(ValueAnimator animation);  
}  
//添加方法为:public void addUpdateListener(AnimatorUpdateListener listener)  
/** 
 * 监听器二:监听动画变化时四个状态 
 */  
public static interface AnimatorListener {  
    void onAnimationStart(Animator animation);  
    void onAnimationEnd(Animator animation);  
    void onAnimationCancel(Animator animation);  
    void onAnimationRepeat(Animator animation);  
}  
//添加方法为:public void addListener(AnimatorListener listener)

插值器与 Evaluator:

/** 
 * 设置插值器 
 */  
public void setInterpolator(TimeInterpolator value)  
/** 
 * 设置 Evaluator 
 */  
public void setEvaluator(TypeEvaluator value) 

更多方法可以查看api

6、AnimatorSet的使用

在视图动画中 AnimationSet 来处理混合动画,同样的,这里的AnimatorSet来处理多个动画的。它出了实现多种动画,还可以精确的进行顺序控制。
示例代码:

ObjectAnimator animator1 = ObjectAnimator.ofFloat(textView, "translationX", 300);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(textView, "scaleX", 1, 0, 1);
ObjectAnimator animator3 = ObjectAnimator.ofFloat(textView, "scaleY", 1, 0, 1);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(1000);
animatorSet.playTogether(animator1, animator2, animator3);
animatorSet.start();

示例效果:

以上示例设置textView在x轴方向移动300,x和y方向先缩小到一倍再还原到一倍三种动画是同时执行。
若需要按顺序执行,可以调用Animator的playSequentially方法。

7、PropertyValuesHolder 的使用

除了上面讲的AnimatorSet 实现多种动画,还可以通过PropertyValuesHolder来实现,比如上面的例子在平移的过程中实现x,y轴的缩放。如下代码;

PropertyValuesHolder valuesHolder1 = PropertyValuesHolder
    .ofFloat("translationX", 300);
PropertyValuesHolder valuesHolder2 = PropertyValuesHolder
    .ofFloat("scaleX", 1, 0, 1);
PropertyValuesHolder valuesHolder3 = PropertyValuesHolder
    .ofFloat("scaleY", 1, 0, 1);
ObjectAnimator.ofPropertyValuesHolder(tv, valuesHolder1,
    valuesHolder2, valuesHolder3).setDuration(1000).start();

运行效果同AnimatorSet中的示例。
它的实现是先分别用PropertyValuesHolder的对象来控制不同的属性,最后调用ofPropertyValuesHolder方法实现多个属性动画的共同作用。

8、在XML文件中实现属性动画

先在xml文件中定义属性,如下示例:

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android">
    android:duration=1000"
    android:propertyName="scaleX"
    android:valueFrom="1.0"
    android:valueTo="2.0"
    android:valueType="floatType"
</objectAnimator>

在java代码代码中使用:

Animator animator = AnimatorInflater.
        loadAnimator(MainActivity.this,
        R.animator.scalex);
animator.setTarget(tv);
animator.start();

需要注意的是,xml文件的定义需要放在res/animator下,而且根节点只能是:set,objectAnimator,valueAnimator三者之一。如果使用的set,可以为其指定播放的方式,属性名为:ordering=[“together”]|[“sequentially”],
默认值为:“together”,对于其他具体的属性这里不再赘述了,可以参见文档。
在实际开发中建议使用代码实现动画,比较简单,而且很多时候某些属性的起始值无法确定。

8、View的animate方法

在android3.0之后,添加了animate方法来直接驱动属性动画,它其实是对属性动画的简写,如下示例:

 view.animate()
        .alpha(0)
        .y(300)
        .setDuration(1000)
        .withStartAction(new Runnable() {
            @Override
            public void run() {

            }
        })
        .withEndAction(new Runnable() {
            @Override
            public void run() {

            }
        }).start();

上面的例子很好理解,可以通过属性来确定他的含义。
总之,在实现动画时,可以根据自己的实际情况选择相应的方式实现动画,必要的时候还可以自定义实现动画,往往在使用时,不只是一种动画,我们要选择合适的方式实现多种动画。


文章作者: imtianx
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC 4.0 许可协议。转载请注明来源 imtianx !
评论
 上一篇
TabLayout+ViewPager创建tab TabLayout+ViewPager创建tab
在degingn库中有TabLayout控件,可以方便的实现tab切换的效果,配合ViewPager.如下展示效果: 1. 添加依design赖库 compile 'com.android.support:design:23.4.0' 2.
下一篇 
Animation 动画详解 Animation 动画详解
在android 开发中,适当的添加动画可以使界面的交互变得更加的友好,特别是在提示,引导类的场景中,合理的使用动画可以带来更好的用户体验。这里,介绍Animation 框架的用法。 1. 概述在 Animation动画框架中提供了四中动画
  目录