欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

动画三、ValueAnimator属性动画的基本使用

程序员文章站 2022-03-17 13:13:17
...

本学习笔记来自启舰的:
http://blog.csdn.net/harvic880925/article/details/50525521

大家都知道逐帧动画主要是用来实现动画的,而补间动画才能实现控件的渐入渐出、移动、旋转和缩放的;而Property Animator是在Android 3.0版本才引入的,之前是没有的。大家可能会觉得补间动画和逐帧动画已经很全了,为什么还要引入Property Animator呢?

1、为什么引入Property Animator(属性动画)

我提出一个假设:请问大家,如何利用补间动画来将一个控件的背景色在一分钟内从绿色变为红色?这个效果想必没办法仅仅通过改变控件的渐入渐出、移动、旋转和缩放来实现吧,而这个效果是可以通过Property Animator完美实现的。

这就是第一个原因:
Property Animator能实现补间动画无法实现的功能

大家都知道,补间动画和逐帧动画统称为View Animation,也就是说这两个动画只能对派生自View的控件实例起作用;而Property Animator则不同,从名字中可以看出属性动画,应该是作用于控件属性的!正因为属性动画能够只针对控件的某一个属性来做动画,所以也就造就了他能单独改变控件的某一个属性的值!比如颜色!这就是Property Animator能实现补间动画无法实现的功能的最重要原因。

我们得到了第二点不同:
View Animation仅能对指定的控件做动画,而Property Animator是通过改变控件某一属性值来做动画的。

假设我们将一个按钮从左上角利用补间动画将其移动到右下角,在移动过程中和移动后,这个按钮都是不会响应点击事件的。这是为什么呢?因为补间动画仅仅转变的是控件的显示位置而已,并没有改变控件本身的值。View Animation的动画实现是通过其Parent View实现的,在View被drawn时Parents View改变它的绘制参数,这样虽然View的大小或旋转角度等改变了,但View的实际属性没变,所以有效区域还是应用动画之前的区域;我们看到的效果仅仅是系统作用在按钮上的显示效果,利用动画把按钮从原来的位置移到了右下角,但按钮内部的任何值是没有变化的,所以按钮所捕捉的操作区域仍是原来的点击区域。(下面会举例来说明这个问题)

这就得到了第三点不同:
View Animation虽能对控件做动画,但并没有改变控件内部的属性值。而Property Animator则是恰恰相反,Property Animator是通过改变控件内部的属性值来达到动画效果的。

2、ValueAnimator 的简单使用

 a、初步使用ValueAnimator
使用ValueAnimaiton,总共有三步:

第一步:创建ValueAnimator实例:
    ValueAnimator animator = ValueAnimator.ofInt(0,400);        
    animator.setDuration(1000);

第二步:添加监听:
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            intcurValue = (int)animation.getAnimatedValue();
            Log.d("qijian","curValue:"+curValue);
       }
    });

第三步:启动动画:
    animator.start();

总而言之就是两点:
(1)、ValueAnimator只负责对指定的数字区间进行动画运算
(2)、我们需要对运算过程进行监听,然后自己对控件做动画操作。详情如下:

private void addAnimatorToTv() {
    intmar = dip2px(this, 55f);
    animator valueAnimator = ValueAnimator.ofInt(mar, 400);
    animator.setDuration(2000);
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animator) {
            inttrasValue = (int) valueAnimator.getAnimatedValue();
            mTvTestObject.layout(trasValue, trasValue, trasValue + mTvTestObject.getWidth(), 
            trasValue + mTvTestObject.getHeight());
        }
    });
    valueAnimator.start();
}

然后再控件的点击事件里面调用该方法即可。

 3、常用方法

(1)、ofInt与ofFloat

public static ValueAnimatorofInt(int... values)
public static ValueAnimatorofFloat(float... values)

他们的参数类型都是可变参数长参数,所以我们可以传入任何数量的值;传进去的值列表,就表示动画时的变化范围;比如ofInt(2,90,45)就表示从数值2变化到数字90再变化到数字45;所以我们传进去的数字越多,动画变化就越复杂。从参数类型也可以看出ofInt与ofFloat的唯一区别就是传入的数字类型不一样.通过getAnimatedValue()来获取当前运动点的值以后,通过layout函数将textview移动到指定位置即可。

(2)、常用函数

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

这里提两点:

a:setDuration()、getAnimatedValue()、start():这三个函数的含义与补间动画的三个函数含义相同,不在累述;
b:setRepeatCount()、setRepeatMode()、cancel():setRepeatCount(int value)设置动画循环次数,0表示不循环,ValueAnimation.INFINITE表示无限循环。cancel()取消动画,这个好理解;

着重说一下setRepeatMode:

它用于设置循环模式,设为ValueAnimation.RESTART,表示正序重新开始,设为ValueAnimation.REVERSE表示倒序重新开始(理解:从0到100运算,重复两次:ValueAnimation.RESTART,0→100,0→100;ValueAnimation.REVERSE:→100,100→0)。

(3)、两个监听器
a、添加监听器
前面,我们讲过一个添加监听器animator.addUpdateListener,以监听动画过程中值的实时变化,其实在ValueAnimator*有两个监听器:

监听器一:AnimatorUpdateListener就是监听动画的实时变化状态,在onAnimationUpdate(ValueAnimator animation)中的animation表示当前状态动画的实例。这个不多讲。

监听器的用法示例:

//监听器一:监听动画变化时的实时值
public static interface AnimatorUpdateListener {
    voidonAnimationUpdate(ValueAnimator animation);
}
//添加方法为:
public void addUpdateListener(AnimatorUpdateListener listener)

//监听器二:监听动画变化时四个状态
public static interface AnimatorListener {
    voidonAnimationStart(Animator animation);
    voidonAnimationEnd(Animator animation);
    voidonAnimationCancel(Animator animation);
    voidonAnimationRepeat(Animator animation);
}
//添加方法为:
public void addListener(AnimatorListener listener)

b、取消监听

//移除AnimatorUpdateListener监听器
voidremoveUpdateListener(AnimatorUpdateListener listener);
voidremoveAllUpdateListeners();

//移除AnimatorListener监听器
voidremoveListener(AnimatorListener listener);
voidremoveAllListeners();
ValueAnimatorvalueAnimator= ValueAnimator.ofInt(0, 450);
valueAnimator.removeAllUpdateListeners();
valueAnimator.removeAllListeners();

(4)、其它函数

public void setStartDelay(long startDelay)//延时多久时间开始,单位是毫秒;

具体用法:
valueAnimator.setStartDelay(1500);
valueAnimator.start();
public ValueAnimator clone()//完全克隆一个ValueAnimator实例(用得少,不多讨论)