ValueAnimator

一句话概括,就是绘制一条二次曲线。

ValueAnimator_第1张图片


      ValueAnimator animator = new ValueAnimator();
        PropertyValuesHolder propertyValuesHolder = PropertyValuesHolder.ofFloat("x", 0, 100, 200, 300);
        animator.setValues(propertyValuesHolder);
        animator.setDuration(2000);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float x = (Float) animation.getAnimatedValue("x");
                textView.setY(x);
            }
        });
        animator.start();

第一个知识点,Keyframe ,关键帧。

它的子类 FloatKeyframe,主要就三个属性 mFraction ,mValue,mInterpolator。

    public static KeyframeSet ofFloat(float... values) {
        boolean badValue = false;
        int numKeyframes = values.length;
        FloatKeyframe keyframes[] = new FloatKeyframe[Math.max(numKeyframes,2)];
        if (numKeyframes == 1) {
            keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f);
            keyframes[1] = (FloatKeyframe) Keyframe.ofFloat(1f, values[0]);
            if (Float.isNaN(values[0])) {
                badValue = true;
            }
        } else {
            keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f, values[0]);
            for (int i = 1; i < numKeyframes; ++i) {
                keyframes[i] =
                        (FloatKeyframe) Keyframe.ofFloat((float) i / (numKeyframes - 1), values[i]);
                if (Float.isNaN(values[i])) {
                    badValue = true;
                }
            }
        }
        if (badValue) {
            Log.w("Animator", "Bad value (NaN) in float animator");
        }
        return new FloatKeyframeSet(keyframes);
    }
最后的 Keyframe 就是 (0,0,null),(1/3,100,null),(2/3,200,null),(1,300,null)。


第二个知识点,Interpolator。

这还是个函数。。。。

最简单的线性函数

public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {

    public LinearInterpolator() {
    }

    public LinearInterpolator(Context context, AttributeSet attrs) {
    }

    public float getInterpolation(float input) {
        return input;
    }

    /** @hide */
    @Override
    public long createNativeInterpolator() {
        return NativeInterpolatorFactoryHelper.createLinearInterpolator();
    }
}
其实就是 y = x 啊。

public class AccelerateDecelerateInterpolator extends BaseInterpolator
        implements NativeInterpolatorFactory {
    public AccelerateDecelerateInterpolator() {
    }

    @SuppressWarnings({"UnusedDeclaration"})
    public AccelerateDecelerateInterpolator(Context context, AttributeSet attrs) {
    }

    public float getInterpolation(float input) {
        return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
    }

    /** @hide */
    @Override
    public long createNativeInterpolator() {
        return NativeInterpolatorFactoryHelper.createAccelerateDecelerateInterpolator();
    }
}
无论是怎么样差值器,总得经过 (0.0) 和 (1,1),不同的只是趋势。


第三,计算 fraction。

分子的意思。

第一次计算:

          float fraction = mDuration > 0 ? (float)(currentTime - mStartTime) / mDuration : 1f;
这代表动画时间已经过去的百分比。

第二次计算:

fraction = mInterpolator.getInterpolation(fraction);
直线可能变成了曲线,经过 (0,0) 和 (1.1)。

第三次计算:

    public float getFloatValue(float fraction) {
        FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0);
        for (int i = 1; i < mNumKeyframes; ++i) {
            FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(i);
            if (fraction < nextKeyframe.getFraction()) {
                final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
                float intervalFraction = (fraction - prevKeyframe.getFraction()) /
                    (nextKeyframe.getFraction() - prevKeyframe.getFraction());
                float prevValue = prevKeyframe.getFloatValue();
                float nextValue = nextKeyframe.getFloatValue();
                // Apply interpolator on the proportional duration.
                if (interpolator != null) {
                    intervalFraction = interpolator.getInterpolation(intervalFraction);
                }
                return mEvaluator == null ?
                        prevValue + intervalFraction * (nextValue - prevValue) :
                        ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
                            floatValue();
            }
            prevKeyframe = nextKeyframe;
        }
        // shouldn't get here
        return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).floatValue();
    }
两帧情况省略了,超过1或者低于0的也忽略了。
关键帧是可以设置差值器的,这意味每两个关键帧之间,可以再一次改变趋势,和之前的差值器叠加在一起。

直到 fraction 到 1 之前,每过 10ms (16ms)会获取下一帧的  value。

基本就是这样。


推荐:

http://blog.csdn.net/xushuaic/article/details/40424379








你可能感兴趣的:(ValueAnimator)