通过源码,手把手带你学属性动画(二) - ValueAnimator基础

转载请注明出处:http://blog.csdn.net/my_truelove/article/details/52612050

访问 ruicb.com,一键抵达我的博客!


主要内容:本文主要讲解 ValueAnimator 的基础使用,以实现简单的值动画效果,为后面学习较高级内容、阅读动画源码打下基础。

在《通过源码,手把手带你学属性动画(一) - 相关类总览》一文中,我们预览了与属性动画相关的类,还没有看的建议去看一下。在上文的最后,提及本篇将讲解 ValueAnimator + ObjectAnimator,但因为篇幅问题,ObjectAnimator 打算放到后面再讲解,本文来着重看一下 ValueAnimator 的基础使用。

说起篇幅,之所以多,是因为从一开始我就想把这系列文章写得清清楚楚,而不是洋洋洒洒想到哪写到哪。我会尽可能站在初学者的角度去考虑问题、去制定学习路线,有些地方对于有一定基础的人可能会觉得繁琐,还请见谅。

下面先介绍 ValueAnimator 的使用,本系列在介绍使用方法时,不会穷举多有方法的使用,只会挑选几个来讲解并分析源码,读者应该举一反三,自行去探索其他方法。

ValueAnimator 官方文档地址

1. ValueAnimator 介绍

先来回顾一下在上文中提及的定义:

本类为运行动画提供了一个简单的计时引擎(timing engine),用来计算动画完成值(animated values)并设置到目标对象上。

接下来将会由浅入深,从创建对象到使用、再到源码分析原理,带你一步步了解 ValueAnimator。

2. 构建 ValueAnimator 对象

先来看看如何得到 ValueAnimator 对象,我们查看其构造方法:

/**
 * Creates a new ValueAnimator object. This default constructor is primarily for
 * use internally; the factory methods which take parameters are more generally
 * useful.
 */
public ValueAnimator() {
}

由方法注释可知,该无参构造方法通常由系统内部调用,我们在使用时,最好使用该类的有参工厂方法来构建 ValueAnimator 对象。

下面我们看看,该类都有哪些构建对象的工厂方法:

通过源码,手把手带你学属性动画(二) - ValueAnimator基础_第1张图片

调用这些方法,可以返回一个 ValueAnimator 对象,接下来我们就可以使用该对象进行动画操作了。

3. 使用 ValueAnimator

上节介绍的5个构造对象的方法,其中 ofArgb()、ofInt()、ofFloat() 方法类似,我们只介绍相对常用的ofFloat()方法,ofArgb()、ofInt() 不再赘述;其余两个不常用,但很重要,还是会介绍,因为在后面的源码分析中会涉及其中的相关知识点,限于篇幅会在下篇介绍。

3.1 ofFloat()方法

下面就以ofFloat()方法为例,介绍如何使用 ValueAnimator,实现对值进行动画。

//定义动画的值范围
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 5f);
//启动动画
valueAnimator.start();

上述简单两行,就实现了值从0f到5f的动画过渡。但是,这仅仅是简单的用法,也看不到任何动画效果。下面,我们使用系统提供的API继续完善该动画过程。

3.2 为动画添加其他属性

以上仅仅实现了简单的动画,实际使用时,系统为我们提供了许多API来帮助我们实现更好的动画效果,下面将一一介绍。值得注意的是,ValueAnimator中 的 API,在 ObjectAnimator 中同样适用,因为后者为前者子类,所以,后期在介绍 ObjectAnimator 时,将不再重申下面要讲的API,只在此介绍一次

1.设置动画时长

系统默认的动画时长为300ms,我们可以通过如下方法自定义动画时长:

//动画时长为100ms
valueAnimator.setDuration(100);

2.设置重复动画

系统使用 int 类型的 mRepeatCount 来标记动画重复的次数,变量注释为:

The number of times the animation will repeat. The default is 0, which means the animation will play only once.

也就是说,动画默认重复0次,即只播放1次。我们可以通过如下方法来设置动画的重复次数:

//设置重复次数,重复1次,则实际播放2次
valueAnimator.setRepeatCount(1);

我们可以设置动画重复的模式,包含REVERSE(逆向重复)和RESTART(重新开始),其中默认为RESTART。我们可以通过如下方法设置动画重复模式:

//设置重复模式:逆向重复
valueAnimator.setRepeatMode(ValueAnimator.REVERSE);
//设置重复模式:重新开始
valueAnimator.setRepeatMode(ValueAnimator.RESTART);

3.监听动画过程

有时候,我们需要获取动画的执行状态,然后做其他操作,比如动画开始、进行中、结束时。在上篇介绍 Animator 类时,说到了其内部接口 Animator.AnimatorListener,可以帮助我们监听动画的过程,不了解的可以去上文查看其内部方法的作用,下面我直接举例:

valueAnimator.addListener(new Animator.AnimatorListener() {
    @Override
    public void onAnimationStart(Animator animation) {
        //动画开始
    }
    @Override
    public void onAnimationEnd(Animator animation) {
        //动画结束
    }
    @Override
    public void onAnimationCancel(Animator animation) {
        //动画取消
    }
    @Override
    public void onAnimationRepeat(Animator animation) {
        //动画重复
    }
});

你可以在对应的方法中实现自己的逻辑。

但是,在实际开发中,我们往往不需要同时关心这么多状态,更多的是关心动画结束,使用接口 AnimatorListener 我们不得不重写所有方法,十分不优雅。这时候,我们可以使用系统为我们提供的适配器类 AnimatorListenerAdapter,该类为抽象类,并实现了 AnimatorListener 接口,然后实现了所有接口方法。这样,我们在使用时,只需要按需重写抽象类相应的方法即可。例如只监听动画结束,使用如下:

valueAnimator.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        //只监听动画结束
    }
});

4.监听动画每一帧的值

上述对值进行动画的过程,我们看不到任何对值进行动画的效果,这时候,我们就需要对动画设置监听,然后来获取动画过程的值。此时,我们可以使用 ValueAnimator 的内部接口 AnimatorUpdateListener,该接口的注释为:

Implementors of this interface can add themselves as update listener to an ValueAnimator instance to receive callbacks on every animation frame, after the current frame’s values have been calculated for that ValueAnimator

注释已经表达的很清楚了,大概意思就是:实现该接口可以对 ValueAnimator 实例添加更新监听,以在每一帧动画时获取回调,此时该帧的动画值已经被计算出来了。

既然如此,我们就可以使用该接口来监听动画值得变化过程,使用方法如下:

//添加对值的监听,获取值
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        //打印
        Log.d("ruicbAndroid", "onAnimationUpdate: value = "
                + animation.getAnimatedValue());
    }
});

这样,系统会在每一帧动画之后通过回调打印出结果。每一帧默认时间为10ms,但具体间隔会根据实际情况有多波动。下面,我们看一下在200ms内,值从0f到10f,且逆向重复1次的动画打印结果。因为设置时长为100ms,且动画重复1次,所以总时长为200ms:

通过源码,手把手带你学属性动画(二) - ValueAnimator基础_第2张图片

5.ofFloat()参数声明

ofFloat(float… values) 方法接收类型为 float 的变长参数,其中第一个值表示开始值,最后一个值表示结束值,中间的值(如果有)表示过渡值。其中每一个值都会被系统当作关键帧处理,当我们传入两个以上的值时,动画过程中将平滑的过渡到中间值所对应的状态。例如,我们可以通过如下代码,让动画从0f过渡到3f,再过渡到5f:

//定义动画的值范围
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 3f, 5f);

4. 总结

本次有关 ValueAnimator 的基础使用就到这儿了,下篇将继续讲一下较高级的内容,你应该先掌握好前两篇较基础的内容,这样在后面学起来才不至于迷糊。

本文将在我的公众号同步推送,感兴趣的可以关注我的公众号,以及时获取推送!

下篇已更新:《通过源码,手把手带你学属性动画(三) - ValueAnimator进阶》


扫描下方二维码,关注我的公众号,及时获取最新文章推送!

你可能感兴趣的:(Android,相关,跟着源码,从零开始学属性动画!)