一句话概括,就是绘制一条二次曲线。
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();
它的子类 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