在Android属性动画源码分析(一)我们说到接下来要进行的从示例1代码开始进行分析(基于API25的源码)。本篇文章要解决的问题是之前一中提到的属性是如何串联起来的,首先,我们看示例1中的第一行代码:
ObjectAnimator animator = ObjectAnimator.ofFloat(this, "test", 0.8f, 1.0f);
进入ofFloat方法:
public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) {
ObjectAnimator anim = new ObjectAnimator(target, propertyName);
anim.setFloatValues(values);
return anim;
}
在上边代码里,新建了一个ObjectAnimation对象,将我们的要进行动画的对象和要修改的属性名称传了进去,并且设置了相应的变化值。我们进入构造方法:
//ObjectAnimator.java
private ObjectAnimator(Object target, String propertyName) {
setTarget(target);
setPropertyName(propertyName);
}
我们来看看这三个值是怎么设置的:
//ObjectAnimator.java
public void setTarget(@Nullable Object target) {
...
mTarget = target == null ? null : new WeakReference<Object>(target);
...
}
setTarget的关键代码中,我们要进行动画的对象以弱引用的形式负值给了mTarget
//ObjectAnimator.java
public void setPropertyName(@NonNull String propertyName) {
// mValues could be null if this is being constructed piecemeal. Just record the
// propertyName to be used later when setValues() is called if so.
if (mValues != null) {
...
}
mPropertyName = propertyName;
}
从该方法的注释可以得知此时mValues是空,所以,该方法将propertyName赋值给了mPropertyName。
//ObjectAnimator.java
@Override
public void setFloatValues(float... values) {
if (mValues == null || mValues.length == 0) {
...
} else {
super.setFloatValues(values);
}
}
这里调用了super.setFloatValues(),我们来看一下ObjectAnimation的类继承关系:
一目了然,我们进入ValueAnimator的setFloatValues方法:
//ValueAnimator.java
public void setFloatValues(float... values) {
if (values == null || values.length == 0) {
return;
}
if (mValues == null || mValues.length == 0) {
setValues(PropertyValuesHolder.ofFloat("", values));
} else {
...
}
...
}
mValues依然没有赋值,走到了setValues方法,并且传入了一个PropertyValueHolder对象。这个对象后面我们再看,先看看setValues做了什么:
//ValueAnimator.java
public void setValues(PropertyValuesHolder... values) {
int numValues = values.length;
mValues = values;
mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
for (int i = 0; i < numValues; ++i) {
PropertyValuesHolder valuesHolder = values[i];
mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
}
...
}
这段代码中,首先给mValues赋值(此时mValues终于不是null了),它存储了所有传入的PropertyValuesHolder,然后根据传入的values数量初始化了mValuesMap(key就是我们要进行动画的属性名,value就是它对应的PropertyValuesHolder)。
至此,我们就将ObjectAnimator.ofFloat方法看完了,下面将看这些源码得到的结论做一个总结:
- 要进行动画的对象放到了mTarget对象中;
- 属性名放到了mPropertyName中;
- 根据属性名,以及给它设定的属性值变化范围,我们生成了一个PropertyValuesHolder对象(如果是ofPropertyHValuseHolder方法是多个,这个方法的原理和ofFloat相同),并初始化了mValues和mValuseMap两个变量,用来存放本次要进行动画的各项信息。
这里我们可以看出属性动画用了PropertyValuesHolder类来存放并管理属性及其相关变化的值的信息,下一篇我们将就刚才初始化时,PropertyValuesHolder.ofFloat("", values)这句话开始进行PropertyValuesHolder类的分析,看看这个类究竟在此时做了什么。
其他部分链接:
[Android属性动画源码分析(三)]
[Android属性动画源码分析(四)]