注:阅读本文,需要对Interpolator和Evaluator有一定了解
不熟悉的同学可以先看看郭霖的系列文章:
链接: http://blog.csdn.net/guolin_blog/article/details/43536355
ValueAnimator用到了几个类,这几个类都有自己的职责。能够把这些先搞清楚的话,再看源码就没那么困难了。
这个类由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
先看几个成员变量:
Keyframe mFirstKeyframe;
Keyframe mLastKeyframe;
List<Keyframe> mKeyframes;
TypeEvaluator mEvaluator
里面保存了多个keyframe以及evaluator,估值(evaluate)由这个类完成,fraction从外面传进来。
那么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搞懂了,下面我们就来看一下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()都干了些啥