转载:http://blog.csdn.net/farmer_cc/article/details/18259117
3. 插值器
从上面的介绍可以看到,Interpolator的关键是getInterpolation();
在ValueAnimator.animationFrame()中可以看到, 传递给Interpolator 的fraction是在[0,1] 值域范围。
- float fraction = mDuration > 0 ? (float)(currentTime - mStartTime) / mDuration : 1f;
- if (fraction >= 1f) {
- if (mCurrentIteration < mRepeatCount || mRepeatCount == INFINITE) {
- // Time to repeat
- if (mListeners != null) {
- int numListeners = mListeners.size();
- for (int i = 0; i < numListeners; ++i) {
- mListeners.get(i).onAnimationRepeat(this);
- }
- }
- if (mRepeatMode == REVERSE) {
- mPlayingBackwards = !mPlayingBackwards;
- }
- mCurrentIteration += (int)fraction;
- fraction = fraction % 1f;
- mStartTime += mDuration;
- } else {
- done = true;
- fraction = Math.min(fraction, 1.0f);
- }
- }
- if (mPlayingBackwards) {
- fraction = 1f - fraction;
- }
所以设计Interpolator 就是设计一个输入[0,1] 的函数。
先参观一下系统的几个Interpolator。
3.1 AccelerateDecelerateInterpolator
cos(t+1)Pi /2 +0.5f
从图可以看到,先加速后减速,病最终到达结束位置。
- public class AccelerateDecelerateInterpolator implements Interpolator {
- public float getInterpolation(float input) {
- return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
- }
- }
3.2 AccelerateInterpolator
如果factor=1 则函数为x^2
否则函数为x^a (a 是参数)
默认函数式x^2
如图示,逐渐加速到结束位置。
- public class AccelerateInterpolator implements Interpolator {
- private final float mFactor;
- private final double mDoubleFactor;
- public AccelerateInterpolator() {
- mFactor = 1.0f;
- mDoubleFactor = 2.0;
- }
- /**
- * Constructor
- *
- * @param factor Degree to which the animation should be eased. Seting
- * factor to 1.0f produces a y=x^2 parabola. Increasing factor above
- * 1.0f exaggerates the ease-in effect (i.e., it starts even
- * slower and ends evens faster)
- */
- public AccelerateInterpolator(float factor) {
- mFactor = factor;
- mDoubleFactor = 2 * mFactor;
- }
- public float getInterpolation(float input) {
- if (mFactor == 1.0f) {
- return input * input;
- } else {
- return (float)Math.pow(input, mDoubleFactor);
- }
- }
- }
3.3 LinearInterpolator
线性的就是Y=X 没啥说的。
- public class LinearInterpolator implements Interpolator {
- public float getInterpolation(float input) {
- return input;
- }
- }
3.4 anticipateInterpolator
函数是:x^2((a+1)x-a) 默认参数a=2 默认函数为x^2(3x-1)
如图示, 会先反方向执行一段,然后正向一直加速至结束位置。
- public class AnticipateInterpolator implements Interpolator {
- private final float mTension;
- public AnticipateInterpolator() {
- mTension = 2.0f;
- }
- /**
- * @param tension Amount of anticipation. When tension equals 0.0f, there is
- * no anticipation and the interpolator becomes a simple
- * acceleration interpolator.
- */
- public AnticipateInterpolator(float tension) {
- mTension = tension;
- }
- public float getInterpolation(float t) {
- // a(t) = t * t * ((tension + 1) * t - tension)
- return t * t * ((mTension + 1) * t - mTension);
- }
- }
3.5 aniticipateOvershoot
是一个分段函数,默认参数a=3
2x*x[(2x*(a+1)-a)] 0<=x<=0.5
2(x-1)(x-1)[(2x-1)(a+1)+a] 0.5<x<=1
通过下图可以看到,动画会先反方向执行,然后向正方向逐渐加速,在快结束时逐渐减速,并超过预设的值,最后回到结束位置。
2x*x[(2x*(a+1)-a)] 0<=x<=0.5 的函数图
2(x-1)(x-1)[(2x-1)(a+1)+a] 0.5<x<=1的函数图
- public class AnticipateOvershootInterpolator implements Interpolator {
- private final float mTension;
- public AnticipateOvershootInterpolator() {
- mTension = 2.0f * 1.5f;
- }
- /**
- * @param tension Amount of anticipation/overshoot. When tension equals 0.0f,
- * there is no anticipation/overshoot and the interpolator becomes
- * a simple acceleration/deceleration interpolator.
- */
- public AnticipateOvershootInterpolator(float tension) {
- mTension = tension * 1.5f;
- }
- /**
- * @param tension Amount of anticipation/overshoot. When tension equals 0.0f,
- * there is no anticipation/overshoot and the interpolator becomes
- * a simple acceleration/deceleration interpolator.
- * @param extraTension Amount by which to multiply the tension. For instance,
- * to get the same overshoot as an OvershootInterpolator with
- * a tension of 2.0f, you would use an extraTension of 1.5f.
- */
- public AnticipateOvershootInterpolator(float tension, float extraTension) {
- mTension = tension * extraTension;
- }
- private static float a(float t, float s) {
- return t * t * ((s + 1) * t - s);
- }
- private static float o(float t, float s) {
- return t * t * ((s + 1) * t + s);
- }
- public float getInterpolation(float t) {
- // a(t, s) = t * t * ((s + 1) * t - s)
- // o(t, s) = t * t * ((s + 1) * t + s)
- // f(t) = 0.5 * a(t * 2, tension * extraTension), when t < 0.5
- // f(t) = 0.5 * (o(t * 2 - 2, tension * extraTension) + 2), when t <= 1.0
- if (t < 0.5f) return 0.5f * a(t * 2.0f, mTension);
- else return 0.5f * (o(t * 2.0f - 2.0f, mTension) + 2.0f);
- }
- }