ValueAnimator源码——整体结构

来源:互联网 发布:收光28网络会丢包吗 编辑:程序博客网 时间:2024/05/21 07:03

注:阅读本文,需要对Interpolator和Evaluator有一定了解
不熟悉的同学可以先看看郭霖的系列文章:
链接: http://blog.csdn.net/guolin_blog/article/details/43536355

ValueAnimator用到了几个类,这几个类都有自己的职责。能够把这些先搞清楚的话,再看源码就没那么困难了。

PropertyValuesHolder

这个类由ValueAnimator直接管理,Evaluation(估值)就是由它完成的
先看一部分成员变量

 String mPropertyName; Keyframes mKeyframes TypeEvaluator mEvaluator; Object mAnimatedValue;

mPropertyName在ObjectAnimator里使用,可以先忽略
mEvaluator 估值要用到它
mAnimatedValue 估值的结果会缓存在这里

至于mKeyframes,我们看看它被赋值的地方
以int型为例:

public void setIntValues(int... values) {        mValueType = int.class;        mKeyframes = KeyframeSet.ofInt(values);}

这个方法的参数就是调用ValueAnimator.ofInt(….)里面的那个int数组
我们看到,mKeyframes实际上是KeyframeSet,KeyframeSet里保存了多个Keyframe,这个类待会再讲。

再看一个方法:

 void calculateValue(float fraction) {        Object value = mKeyframes.getValue(fraction);        mAnimatedValue = mConverter == null ? value : mConverter.convert(value);}

Converter先不管
这个方法的参数是经过interpolator处理的结果,由mKeyframes(即KeyframeSet)计算出最终的属性值,保存在mAnimatedValue
再通过getAnimatedValue()就能获得mAnimatedValue

总结:PropertyValuesHolder这个类主要负责缓存结果,估值计算由KeyframeSet负责。设置evaluator时,evaluator会传给keyframeSet

KeyframeSet

先看几个成员变量:

  Keyframe mFirstKeyframe;  Keyframe mLastKeyframe;  List<Keyframe> mKeyframes;  TypeEvaluator mEvaluator

里面保存了多个keyframe以及evaluator,估值(evaluate)由这个类完成,fraction从外面传进来。
那么Keyframe是什么呢?

Keyframe

简单来说,keyframe记录了一个端点的值,和对应的进度。
举个例子,我们看KeyframeSet的一个静态工厂方法:ofInt(int[] )
这个int数组就是ValueAnimator.ofInt(….)那个参数。

public static KeyframeSet ofInt(int... values) {        int numKeyframes = values.length;        IntKeyframe keyframes[] = new IntKeyframe[Math.max(numKeyframes,2)];        if (numKeyframes == 1) {            keyframes[0] = (IntKeyframe) Keyframe.ofInt(0f);            keyframes[1] = (IntKeyframe) Keyframe.ofInt(1f, values[0]);        } else {            keyframes[0] = (IntKeyframe) Keyframe.ofInt(0f, values[0]);            for (int i = 1; i < numKeyframes; ++i) {                keyframes[i] =                        (IntKeyframe) Keyframe.ofInt((float) i / (numKeyframes - 1), values[i]);            }        }        return new IntKeyframeSet(keyframes);    }

里面会构造一个keyframe数组,按照均等分来的。
例如,传入的int[]长度为5, 为{a1, a2, a3, a4, a5} 这5个数字有4个间隔,每个间隔占0.25, 那么会构造5个keyframe。
Keyframe.ofInt(float fraction, int value)就是构造一个IntKeyframe,传入的2个参数会被保存起来,通过getFraction和getValue方法可以获取。

最后生成的keyframe应该是这样

keyframe

Keyframe搞懂了,下面我们就来看一下KeyframeSet是如何根据fraction计算出具体的属性值。
核心部分就在KeyframeSet的getValue(float fraction)方法中:
源码比较长,我就不贴了~

分了4种情况,第一种情况是只有2个keyframe,直接调用evaluator就行。
注意:这里有一个mInterpolator,并不是我们给valueAnimator设置的那个Interpolator!这个东西其实是从keyframe那里获得的,当使用Android自带的工厂方法构造keyframe时,interpolator为null。
所以这个mInterpolator一般为null, 下面看到的interpolator都是这样的。

第二种情况,fraction<=0: 那就认为这个fraction落在第一个和第二个keyframe之间,计算

第三种情况,fraction>=1: 那就认为落在最后2个keyframe之间,计算

第四种情况,fraction在0到1之间: 那就找出落在哪2个keyframe之间,再计算
其实还是挺简单的

总的来看,keyframe保存端点的信息,keyframSet根据keyframe和fraction,计算出具体属性值。PropertyValuesHolder对计算结果缓存,以及一系列处理工作。

结构讲到这里,下一篇会看fraction到底是怎么来的
start()都干了些啥

原创粉丝点击