ValueAnimator

来源:互联网 发布:最好的扫描识别软件 编辑:程序博客网 时间:2024/06/08 13:07

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



      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








0 0
原创粉丝点击