这里从最基本的使用分析源码,平时我们使用属性动画如下:
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(tv,"alpha",1.0f,0.3f,1.0f);//初始化动画
objectAnimator.setDuration(200);
objectAnimator.start();//动画开始时从start方法开始的
先来分析下ofFloat
这个方法,这个方法是在ObjectAnimator
这个类中,如下:
public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) {
ObjectAnimator anim = new ObjectAnimator(target, propertyName);//实例化ObjectAnimator
anim.setFloatValues(values);//设置属性值
return anim;
}
这个方法做了两件事:
1)实例化了ObjectAnimator
这个对象
首先看下ObjectAnimator
这个构造方法:
private ObjectAnimator(Object target, String propertyName) {
setTarget(target);//保存要执行对象的动画
setPropertyName(propertyName);//设置要执行动画的对象的属性
}
看下setTarget
这个方法:
@Override
public void setTarget(@Nullable Object target) {
final Object oldTarget = getTarget();
if (oldTarget != target) {
if (isStarted()) {
cancel();
}
//将传入的目标对象使用WeakReference包裹,然后赋值给mTarget
mTarget = target == null ? null : new WeakReference
然后返回看下ObjectAnimator
这个构造方法中的setPropertyName
这个方法:
public void setProperty(@NonNull Property property) {
if (mValues != null) {
//这里可以看到使用PropertyValuesHolder对属性值进行了保存
PropertyValuesHolder valuesHolder = mValues[0];
String oldName = valuesHolder.getPropertyName();
valuesHolder.setProperty(property);
mValuesMap.remove(oldName);
mValuesMap.put(mPropertyName, valuesHolder);
}
if (mProperty != null) {
mPropertyName = property.getName();
}
mProperty = property;
//mInitialized还是false
mInitialized = false;
}
2)对动画设置属性值
我们查看一下setFloatValues
这个方法,这个方法是设置属性和属性值,核心代码如下:
if (mProperty != null) {
setValues(PropertyValuesHolder.ofFloat(mProperty, values));
} else {
setValues(PropertyValuesHolder.ofFloat(mPropertyName, values));
}
PropertyValuesHolder
是属性值持有者,它保存了动画过程中所需要操作的属性和对应的值,我们通过ofFloat()构造的动画,ofFloat()的内部实现其实就是将传进来的参数封装成PropertyValuesHolder实例化来保存动画的值
接着先看下setValues
这个方法:
public void setValues(PropertyValuesHolder... values) {
int numValues = values.length;
mValues = values;
mValuesMap = new HashMap(numValues);
for (int i = 0; i < numValues; ++i) {
PropertyValuesHolder valuesHolder = values[i];
mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
}
mInitialized = false;
}
可以看到将属性值保存到了HashMap中,然后返回看下PropertyValuesHolder.ofFloat
中的ofFloat
这个方法:
public static PropertyValuesHolder ofFloat(Property, Float> property, float... values) {//参数为属性和属性值
return new FloatPropertyValuesHolder(property, values);
}
实际上是通过PropertyValuesHolder
的子类FloatPropertyValuesHolder
来保存属性和属性值的。
然后我们看点FloatPropertyValuesHolder
的构造方法做了什么事:
public FloatPropertyValuesHolder(Property property, float... values) {
super(property);
setFloatValues(values);
if (property instanceof FloatProperty) {
mFloatProperty = (FloatProperty) mProperty;
}
}
查看下setFloatValues(values);
,如下:
@Override
public void setFloatValues(float... values) {
super.setFloatValues(values);//这里又调用了它父类的setFloatValues() 看这个方法
mFloatKeyframes = (Keyframes.FloatKeyframes) mKeyframes;
}
看下super.setFloatValues(values);
的setFloatValues
这个方法:
//PropertyValuesHolder类
public void setFloatValues(float... values) {
mValueType = float.class;
mKeyframes = KeyframeSet.ofFloat(values);
}
KeyframeSet
意为关键帧,设置了关键帧后,动画就可以在各个关键帧之间平滑过渡,一个关键帧必须包含两个元素(时间点和位置),即这个关键帧是表示的是某个物体在哪个时间点应该在哪个位置上。fraction表示当前位置,value表示当前位置。
总结:ObjectAnimator
通过ofFloat
方法初始化后,内部通过HashMap保存了属性(key)和属性值(value),属性值通过PropertyValuesHolder
保存的,PropertyValuesHolder
是属性值持有者,它保存了动画过程中所需要操作的属性和对应的值,我们通过ofFloat()构造的动画,ofFloat()的内部实现其实就是将传进来的参数封装成PropertyValuesHolder实例化来保存动画的值,但是实际上是通过PropertyValuesHolder
的子类FloatPropertyValuesHolder
来保存属性和属性值的。最终通过设置关键帧,动画就可以在各个关键帧之间平滑过渡,一个关键帧必须包含两个元素(时间点和位置),即这个关键帧是表示的是某个物体在哪个时间点应该在哪个位置上。
属性动画源码分析-start方法