×

Android属性动画源码分析(二)

96
古龙小蓝瓶
2017.06.14 17:17* 字数 612

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的类继承关系:

Paste_Image.png

  一目了然,我们进入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类的分析,看看这个类究竟在此时做了什么。

日记本
Web note ad 1