最后start()。
好了,现在我想问个问题,根据上面这些参数,如果我要你设计个属性动画框架,你怎么做?
这个嘛,好整,拿到上述参数之后,start()中,开启一个定时器,去执行一个任务;在任务内部,根据Interpolator计算出来的fraction,交给Evaluator,得到属性当前应该设置的值,然后反射设置tagert的指定属性,ok,奏事这么简单。嗯,大体上应该就是这样,当然了,源码的实现肯定复杂很多,但是万变不离其宗,所以接下来的源码阅读,就是去验证我们的这个答案。
3、源码分析
======
好了,猜想完了,我们就得进入验证阶段了~~
那么,我们源码的入口就是上述代码了,不过貌似上述代码调用了好几个方法,but,我觉得start之前的代码,无法是初始化实例,设置一些成员变量。
首先我们看ofInt,这里为了简单,我们的ofInt中的values参数,默认就一个,类似 .ofInt(view, “translationX”, 300) ;
1、ofInt
public static ObjectAnimator ofInt(Object target, String propertyName, int… values) {
ObjectAnimator anim = new ObjectAnimator(target, propertyName);
anim.setIntValues(values);
return anim;
}
首先调用ObjectAnimator的构造方法传入了一个target和propName,估计就是创建对象,然后旧路下target和propName,简单看下
private ObjectAnimator(Object target, String propertyName) {
mTarget = target;
setPropertyName(propertyName);
}
public void setPropertyName(String propertyName) {
//…
mPropertyName = propertyName;
mInitialized = false;
}
记录完成target,propName以后,调用setIntValues
@Override
public void setIntValues(int… values) {
setValues(PropertyValuesHolder.ofInt(mPropertyName, values));
}
可以看到,把我们的propName,和values传入到了一个PropertyValuesHolder的ofInt方法中,去构造一个PropertyValuesHolder对象,这个对象是干什么的呢?
从字面上看,是保存view在动画期间的属性和值,记住是动画期间的。继续往下看:
public static PropertyValuesHolder ofInt(String propertyName, int… values) {
return new IntPropertyValuesHolder(propertyName, values);
}
public IntPropertyValuesHolder(String propertyName, int… values) {
mPropertyName = propertyName;
setIntValues(values);
}
@Override
public void setIntValues(int… values) {
mValueType = int.class;
mKeyframeSet = KeyframeSet.ofInt(values);
mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet;
}
可以看到在IntPropertyValuesHolder内部存储了我们的propertyName;,然后又调用了setIntValues,存储了我们的mValueType ,此外还存了一个mIntKeyframeSet。
这里又出现一个新名词,叫做mKeyframeSet,这个是由 KeyframeSet.ofInt(values);得到的。
那么这个KeyframeSet是什么呢?单纯的理解是,Keyframe的集合,而Keyframe叫做关键帧,为一个动画保存time/value(时间与值)对。
那么我们去看看它是如何通过KeyframeSet.ofInt(values);去构造与保存的:
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 {
//…
}
return new IntKeyframeSet(keyframes);
}
public IntKeyframeSet(IntKeyframe… keyframes) {
mNumKeyframes = keyframes.length;
mKeyframes = new ArrayList();
mKeyframes.addAll(Arrays.asList(keyframes));
mFirstKeyframe = mKeyframes.get(0);
mLastKeyframe = mKeyframes.get(mNumKeyframes - 1);
mInterpolator = mLastKeyframe.getInterpolator();
}
这里代码跳跃比较大,部分代码我来解释:
根据我们的values的长度,构造了keyframes数组,然后分别通过Keyframe的ofInt方法,去构造keyframe对象,其实在内部:
IntKeyframe(float fraction, int value) {
mFraction = fraction;
mV