ValueAnimator源码——整体结构

注:阅读本文,需要对Interpolator和Evaluator有一定了解
不熟悉的同学可以先看看郭霖的系列文章:
链接: http://blog.csdn.net/guolin_blog/article/details/43536355

ValueAnimator用到了几个类,这几个类都有自己的职责。能够把这些先搞清楚的话,再看源码就没那么困难了。

PropertyValuesHolder

这个类由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

KeyframeSet

先看几个成员变量:

  Keyframe mFirstKeyframe;
  Keyframe mLastKeyframe;
  List<Keyframe> mKeyframes;
  TypeEvaluator mEvaluator

里面保存了多个keyframe以及evaluator,估值(evaluate)由这个类完成,fraction从外面传进来。
那么Keyframe是什么呢?

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

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()都干了些啥

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值