java Android缓动功能。动画集合,有助于简化动画。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java Android缓动功能。动画集合,有助于简化动画。相关的知识,希望对你有一定的参考价值。

/*
 * Copyright (C) 2015 Jared Rummler <jared.rummler@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.jrummyapps.android.animations;

import android.animation.PropertyValuesHolder;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;

import java.util.ArrayList;

/**
 * <p>Android easing functions. An animation collection to help make animation easier.</p>
 *
 * <p>Example usage:</p>
 *
 * <pre>
 * <code>
 * AnimatorSet set = new AnimatorSet();
 * set.playTogether(Skill.BOUNCE_EASE_IN_OUT.glide(
 *     1200, ObjectAnimator.ofFloat(view, "translationY", 0, 100)));
 * set.setDuration(1200);
 * set.start();
 * </code>
 * </pre>
 *
 * See <a href="https://github.com/daimajia/AnimationEasingFunctions">AnimationEasingFunctions</a>
 */
public enum Skill {
  BACK_EASE_IN {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          return c * (t /= d) * t * ((1.70158f + 1) * t - 1.70158f) + b;
        }
      };
    }
  },
  BACK_EASE_IN_OUT {
    @Override public EasingMethod getMethod(float duration) {
      return getMethod(duration, 1.70158f);
    }

    public EasingMethod getMethod(float duration, final float back) {
      return new EasingMethod(duration) {

        private float s = back;

        @Override public float calculate(float t, float b, float c, float d) {
          return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
        }
      };
    }
  },
  BACK_EASE_OUT {
    @Override public EasingMethod getMethod(float duration) {
      return getMethod(duration, 1.70158f);
    }

    public EasingMethod getMethod(float duration, final float back) {
      return new EasingMethod(duration) {

        private float s = back;

        @Override public float calculate(float t, float b, float c, float d) {
          return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
        }
      };
    }

  },
  BOUNCE_EASE_IN {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        private final EasingMethod bounceEaseOut = BOUNCE_EASE_OUT.getMethod(duration);

        @Override public float calculate(float t, float b, float c, float d) {
          return c - bounceEaseOut.calculate(d - t, 0, c, d) + b;
        }
      };
    }
  },
  BOUNCE_EASE_IN_OUT {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        private final EasingMethod bounceEaseOut = BOUNCE_EASE_OUT.getMethod(duration);

        private final EasingMethod bounceEaseIn = BOUNCE_EASE_IN.getMethod(duration);

        @Override public float calculate(float t, float b, float c, float d) {
          if (t < d / 2) {
            return bounceEaseIn.calculate(t * 2, 0, c, d) * .5f + b;
          } else {
            return bounceEaseOut.calculate(t * 2 - d, 0, c, d) * .5f + c * .5f + b;
          }
        }
      };
    }
  },
  BOUNCE_EASE_OUT {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          if ((t /= d) < (1 / 2.75f)) {
            return c * (7.5625f * t * t) + b;
          } else if (t < (2 / 2.75f)) {
            return c * (7.5625f * (t -= (1.5f / 2.75f)) * t + .75f) + b;
          } else if (t < (2.5 / 2.75)) {
            return c * (7.5625f * (t -= (2.25f / 2.75f)) * t + .9375f) + b;
          } else {
            return c * (7.5625f * (t -= (2.625f / 2.75f)) * t + .984375f) + b;
          }
        }
      };
    }
  },
  CIRC_EASE_IN {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          return -c * ((float) Math.sqrt(1 - (t /= d) * t) - 1) + b;
        }
      };
    }
  },
  CIRC_EASE_IN_OUT {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          if ((t /= d / 2) < 1) {
            return -c / 2 * ((float) Math.sqrt(1 - t * t) - 1) + b;
          }
          return c / 2 * ((float) Math.sqrt(1 - (t -= 2) * t) + 1) + b;
        }
      };
    }
  },
  CIRC_EASE_OUT {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          return c * (float) Math.sqrt(1 - (t = t / d - 1) * t) + b;
        }
      };
    }
  },
  ELASTIC_EASE_IN {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          if (t == 0) {
            return b;
          }
          if ((t /= d) == 1) {
            return b + c;
          }
          float p = d * .3f;
          float a = c;
          float s = p / 4;
          return -(a * (float) Math.pow(2, 10 * (t -= 1)) * (float) Math.sin((t * d - s)
              * (2 * (float) Math.PI) / p)) + b;
        }
      };
    }
  },
  ELASTIC_EASE_IN_OUT {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          if (t == 0) {
            return b;
          }
          if ((t /= d / 2) == 2) {
            return b + c;
          }
          float p = d * (.3f * 1.5f);
          float a = c;
          float s = p / 4;
          if (t < 1) {
            return -.5f
                * (a * (float) Math.pow(2, 10 * (t -= 1)) * (float) Math.sin((t * d - s)
                * (2 * (float) Math.PI) / p)) + b;
          }
          return a * (float) Math.pow(2, -10 * (t -= 1))
              * (float) Math.sin((t * d - s) * (2 * (float) Math.PI) / p) * .5f + c + b;
        }
      };
    }
  },
  ELASTIC_EASE_OUT {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          if (t == 0) {
            return b;
          }
          if ((t /= d) == 1) {
            return b + c;
          }
          float p = d * .3f;
          float a = c;
          float s = p / 4;
          return (a * (float) Math.pow(2, -10 * t)
              * (float) Math.sin((t * d - s) * (2 * (float) Math.PI) / p) + c + b);
        }
      };
    }
  },
  EXPO_EASE_IN {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          return (t == 0) ? b : c * (float) Math.pow(2, 10 * (t / d - 1)) + b;
        }
      };
    }
  },
  EXPO_EASE_IN_OUT {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          if (t == 0) {
            return b;
          }
          if (t == d) {
            return b + c;
          }
          if ((t /= d / 2) < 1) {
            return c / 2 * (float) Math.pow(2, 10 * (t - 1)) + b;
          }
          return c / 2 * (-(float) Math.pow(2, -10 * --t) + 2) + b;
        }
      };
    }
  },
  EXPO_EASE_OUT {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          return (t == d) ? b + c : c * (-(float) Math.pow(2, -10 * t / d) + 1) + b;
        }
      };
    }
  },
  LINEAR {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          return c * t / d + b;
        }
      };
    }
  },
  QUAD_EASE_IN {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          return c * (t /= d) * t + b;
        }
      };
    }
  },
  QUAD_EASE_IN_OUT {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          if ((t /= d / 2) < 1) {
            return c / 2 * t * t + b;
          }
          return -c / 2 * ((--t) * (t - 2) - 1) + b;
        }
      };
    }
  },
  QUAD_EASE_OUT {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          return -c * (t /= d) * (t - 2) + b;
        }
      };
    }
  },
  QUINT_EASE_IN {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          return c * (t /= d) * t * t * t * t + b;
        }
      };
    }
  },
  QUINT_EASE_IN_OUT {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          if ((t /= d / 2) < 1) {
            return c / 2 * t * t * t * t * t + b;
          }
          return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
        }
      };
    }
  },
  QUINT_EASE_OUT {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
        }
      };
    }
  },
  SINE_EASE_IN {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          return -c * (float) Math.cos(t / d * (Math.PI / 2)) + c + b;
        }
      };
    }
  },
  SINE_EASE_IN_OUT {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          return -c / 2 * ((float) Math.cos(Math.PI * t / d) - 1) + b;
        }
      };
    }
  },
  SINE_EASE_OUT {
    @Override public EasingMethod getMethod(float duration) {
      return new EasingMethod(duration) {

        @Override public float calculate(float t, float b, float c, float d) {
          return c * (float) Math.sin(t / d * (Math.PI / 2)) + b;
        }
      };
    }
  };

  public abstract EasingMethod getMethod(float duration);

  public ValueAnimator glide(float duration, ValueAnimator animator) {
    return glide(duration, animator, null);
  }

  public ValueAnimator glide(float duration, ValueAnimator animator,
                             EasingMethod.EasingListener... listeners) {
    EasingMethod method = getMethod(duration);
    if (listeners != null && listeners.length > 0) {
      method.addEasingListeners(listeners);
    }
    animator.setEvaluator(method);
    return animator;
  }

  public PropertyValuesHolder glide(float duration, PropertyValuesHolder propertyValuesHolder) {
    propertyValuesHolder.setEvaluator(getMethod(duration));
    return propertyValuesHolder;
  }

  public static abstract class EasingMethod implements TypeEvaluator<Number> {

    private final ArrayList<EasingListener> listeners = new ArrayList<>();

    protected float duration;

    public EasingMethod(float duration) {
      this.duration = duration;
    }

    public void addEasingListener(EasingListener listener) {
      listeners.add(listener);
    }

    public void addEasingListeners(EasingListener... listeners) {
      for (EasingListener listener : listeners) {
        this.listeners.add(listener);
      }
    }

    public void removeEasingListener(EasingListener listener) {
      listeners.remove(listener);
    }

    public void clearEasingListeners() {
      listeners.clear();
    }

    public void setDuration(float duration) {
      this.duration = duration;
    }

    @Override public final Float evaluate(float fraction, Number startValue, Number endValue) {
      float t = duration * fraction;
      float b = startValue.floatValue();
      float c = endValue.floatValue() - startValue.floatValue();
      float d = duration;
      float result = calculate(t, b, c, d);
      for (EasingListener l : listeners) {
        l.on(t, result, b, c, d);
      }
      return result;
    }

    public abstract float calculate(float t, float b, float c, float d);

    public interface EasingListener {

      void on(float time, float value, float start, float end, float duration);
    }

  }

}
/*
 * Copyright (C) 2015 Jared Rummler <jared.rummler@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.jrummyapps.android.animations;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;

import java.util.ArrayList;
import java.util.List;

/**
 * <h1>Collection of animations.</h1>
 *
 * <h4>Effects</h4>
 *
 * <h4>Attention:</h4>
 * <p>FLASH, PULSE, RUBBER_BAND, SHAKE, SWING, WOBBLE, BOUNCE, TADA, STAND_UP, WAVE</p>
 *
 * <h4>Special:</h4>
 * <p>HINGE, ROLL_IN, ROLL_OUT, LANDING, TAKING_OFF, DROP_OUT</p>
 *
 * <h4>Bounce:</h4>
 * <p>BOUNCE_IN, BOUNCE_IN_DOWN, BOUNCE_IN_LEFT, BOUNCE_IN_RIGHT, BOUNCE_IN_UP</p>
 *
 * <h4>Fade:</h4>
 * <p>FADE_IN, FADE_IN_UP, FADE_IN_DOWN, FADE_IN_LEFT, FADE_IN_RIGHT, FADE_OUT, FADE_OUT_DOWN,
 * FADE_OUT_LEFT, FADE_OUT_RIGHT, FADE_OUT_UP</p>
 *
 * <h4>Flip:</h4>
 * <p>FLIP_IN_X, FLIP_OUT_X, FLIP_OUT_Y</p>
 *
 * <h4>Rotate:</h4>
 * <p>ROTATE, ROTATE_IN, ROTATE_IN_DOWN_LEFT, ROTATE_IN_DOWN_RIGHT, ROTATE_IN_UP_LEFT,
 * ROTATE_IN_UP_RIGHT, ROTATE_OUT, ROTATE_OUT_DOWN_LEFT, ROTATE_OUT_DOWN_RIGHT, ROTATE_OUT_UP_LEFT,
 * ROTATE_OUT_UP_RIGHT</p>
 *
 * <h4>Slide:</h4>
 * <p>SLIDE_IN_LEFT, SLIDE_IN_RIGHT, SLIDE_IN_UP, SLIDE_IN_DOWN, SLIDE_OUT_LEFT, SLIDE_OUT_RIGHT,
 * SLIDE_OUT_UP, SLIDE_OUT_DOWN</p>
 *
 * <h4>Zoom:</h4>
 * <p>ZOOM_IN, ZOOM_IN_DOWN, ZOOM_IN_LEFT, ZOOM_IN_RIGHT, ZOOM_IN_UP, ZOOM_OUT, ZOOM_OUT_DOWN,
 * ZOOM_OUT_LEFT, ZOOM_OUT_RIGHT, ZOOM_OUT_UP</p>
 *
 * <p>Example usage:</p>
 * <pre><code>
 *   Technique.BOUNCE.playOn(view);
 * </code></pre>
 *
 * Based off <a href="https://github.com/daimajia/AndroidViewAnimations">AndroidViewAnimations</a>
 */
public enum Technique {

  /* ------------------------------------------------------------------------------------------- */
  /* Attention
  /* ------------------------------------------------------------------------------------------- */

  FLASH {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 0, 1, 0, 1));
        }
      };
    }
  },
  PULSE {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "scaleY", 1, 1.1f, 1),
              ObjectAnimator.ofFloat(target, "scaleX", 1, 1.1f, 1));
        }
      };
    }
  },
  RUBBER_BAND {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(
              ObjectAnimator.ofFloat(target, "scaleX", 1, 1.25f, 0.75f, 1.15f, 1),
              ObjectAnimator.ofFloat(target, "scaleY", 1, 0.75f, 1.25f, 0.85f, 1));
        }
      };
    }
  },
  SHAKE {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(
              ObjectAnimator.ofFloat(target, "translationX",
                  0, 25, -25, 25, -25, 15, -15, 6, -6, 0));
        }
      };
    }
  },
  SWING {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(
              ObjectAnimator.ofFloat(target, "rotation", 0, 10, -10, 6, -6, 3, -3, 0));
        }
      };
    }
  },
  WOBBLE {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          float width = target.getWidth();
          float one = (float) (width / 100.0);
          getAnimatorSet().playTogether(
              ObjectAnimator.ofFloat(target, "translationX",
                  0 * one, -25 * one, 20 * one, -15 * one, 10 * one, -5 * one, 0 * one, 0),
              ObjectAnimator.ofFloat(target, "rotation",
                  0, -5, 3, -3, 2, -1, 0));
        }
      };
    }
  },
  BOUNCE {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(
              ObjectAnimator.ofFloat(target, "translationY", 0, 0, -30, 0, -15, 0, 0));
        }
      };
    }
  },
  TADA {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(
              ObjectAnimator.ofFloat(target, "scaleX",
                  1, 0.9f, 0.9f, 1.1f, 1.1f, 1.1f, 1.1f, 1.1f, 1.1f, 1),
              ObjectAnimator.ofFloat(target, "scaleY",
                  1, 0.9f, 0.9f, 1.1f, 1.1f, 1.1f, 1.1f, 1.1f, 1.1f, 1),
              ObjectAnimator.ofFloat(target, "rotation",
                  0, -3, -3, 3, -3, 3, -3, 3, -3, 0));
        }
      };
    }
  },
  STAND_UP {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          float x = (target.getWidth() - target.getPaddingLeft() - target.getPaddingRight()) / 2
              + target.getPaddingLeft();
          float y = target.getHeight() - target.getPaddingBottom();
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "pivotX", x, x, x, x, x),
              ObjectAnimator.ofFloat(target, "pivotY", y, y, y, y, y),
              ObjectAnimator.ofFloat(target, "rotationX", 55, -30, 15, -15, 0));
        }
      };
    }
  },
  WAVE {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          float x = (target.getWidth() - target.getPaddingLeft() - target.getPaddingRight()) / 2
              + target.getPaddingLeft();
          float y = target.getHeight() - target.getPaddingBottom();
          getAnimatorSet().playTogether(
              ObjectAnimator.ofFloat(target, "rotation", 12, -12, 3, -3, 0),
              ObjectAnimator.ofFloat(target, "pivotX", x, x, x, x, x),
              ObjectAnimator.ofFloat(target, "pivotY", y, y, y, y, y));
        }
      };
    }
  },

  /* ------------------------------------------------------------------------------------------- */
  /* Special
  /* ------------------------------------------------------------------------------------------- */

  HINGE {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          float x = target.getPaddingLeft();
          float y = target.getPaddingTop();
          getAnimatorSet().playTogether(
              Skill.SINE_EASE_IN_OUT.glide(1300,
                  ObjectAnimator.ofFloat(target, "rotation", 0, 80, 60, 80, 60, 60)),
              ObjectAnimator.ofFloat(target, "translationY", 0, 0, 0, 0, 0, 700),
              ObjectAnimator.ofFloat(target, "alpha", 1, 1, 1, 1, 1, 0),
              ObjectAnimator.ofFloat(target, "pivotX", x, x, x, x, x, x),
              ObjectAnimator.ofFloat(target, "pivotY", y, y, y, y, y, y));

          setDuration(1300);
        }
      };
    }
  },
  ROLL_IN {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(
              ObjectAnimator.ofFloat(target, "alpha", 0, 1),
              ObjectAnimator.ofFloat(target, "translationX",
                  -(target.getWidth() - target.getPaddingLeft() - target.getPaddingRight()), 0),
              ObjectAnimator.ofFloat(target, "rotation", -120, 0));
        }
      };
    }
  },
  ROLL_OUT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 0),
              ObjectAnimator.ofFloat(target, "translationX", 0, target.getWidth()),
              ObjectAnimator.ofFloat(target, "rotation", 0, 120));
        }
      };
    }
  },
  LANDING {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          long duration = getAnimatorSet().getDuration();
          getAnimatorSet().playTogether(
              Skill.QUINT_EASE_OUT.glide(duration,
                  ObjectAnimator.ofFloat(target, "scaleX", 1.5f, 1f)),
              Skill.QUINT_EASE_OUT.glide(duration,
                  ObjectAnimator.ofFloat(target, "scaleY", 1.5f, 1f)),
              Skill.QUINT_EASE_OUT.glide(duration,
                  ObjectAnimator.ofFloat(target, "alpha", 0, 1f)));
        }
      };
    }
  },
  TAKING_OFF {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          long duration = getAnimatorSet().getDuration();
          getAnimatorSet().playTogether(
              Skill.QUINT_EASE_OUT
                  .glide(duration, ObjectAnimator.ofFloat(target, "scaleX", 1f, 1.5f)),
              Skill.QUINT_EASE_OUT
                  .glide(duration, ObjectAnimator.ofFloat(target, "scaleY", 1f, 1.5f)),
              Skill.QUINT_EASE_OUT
                  .glide(duration, ObjectAnimator.ofFloat(target, "alpha", 1, 0)));
        }
      };
    }
  },
  DROP_OUT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          int distance = target.getTop() + target.getHeight();
          getAnimatorSet().playTogether(
              ObjectAnimator.ofFloat(target, "alpha", 0, 1),
              Skill.BOUNCE_EASE_OUT.glide(getAnimatorSet().getDuration(),
                  ObjectAnimator.ofFloat(target, "translationY", -distance, 0))
          );
        }
      };
    }
  },

  /* ------------------------------------------------------------------------------------------- */
  /* Bounce
  /* ------------------------------------------------------------------------------------------- */

  BOUNCE_IN {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 0, 1, 1, 1),
              ObjectAnimator.ofFloat(target, "scaleX", 0.3f, 1.05f, 0.9f, 1),
              ObjectAnimator.ofFloat(target, "scaleY", 0.3f, 1.05f, 0.9f, 1));
        }
      };
    }
  },
  BOUNCE_IN_DOWN {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 0, 1, 1, 1),
              ObjectAnimator.ofFloat(target, "translationY", -target.getHeight(), 30, -10, 0));
        }
      };
    }
  },
  BOUNCE_IN_LEFT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(
              ObjectAnimator.ofFloat(target, "translationX", -target.getWidth(), 30, -10, 0),
              ObjectAnimator.ofFloat(target, "alpha", 0, 1, 1, 1));
        }
      };
    }
  },
  BOUNCE_IN_RIGHT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(
              ObjectAnimator.ofFloat(target, "translationX",
                  target.getMeasuredWidth() + target.getWidth(), -30, 10, 0),
              ObjectAnimator.ofFloat(target, "alpha", 0, 1, 1, 1));
        }
      };
    }
  },
  BOUNCE_IN_UP {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(
              ObjectAnimator
                  .ofFloat(target, "translationY", target.getMeasuredHeight(), -30, 10, 0),
              ObjectAnimator.ofFloat(target, "alpha", 0, 1, 1, 1));
        }
      };
    }
  },

  /* ------------------------------------------------------------------------------------------- */
  /* Fade
  /* ------------------------------------------------------------------------------------------- */

  FADE_IN {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 0, 1));
        }
      };
    }
  },
  FADE_IN_UP {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 0, 1),
              ObjectAnimator.ofFloat(target, "translationY", target.getHeight() / 4, 0));
        }
      };
    }
  },
  FADE_IN_DOWN {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 0, 1),
              ObjectAnimator.ofFloat(target, "translationY", -target.getHeight() / 4, 0));
        }
      };
    }
  },
  FADE_IN_LEFT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 0, 1),
              ObjectAnimator.ofFloat(target, "translationX", -target.getWidth() / 4, 0));
        }
      };
    }
  },
  FADE_IN_RIGHT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 0, 1),
              ObjectAnimator.ofFloat(target, "translationX", target.getWidth() / 4, 0));
        }
      };
    }
  },
  FADE_OUT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 0));
        }
      };
    }
  },
  FADE_OUT_DOWN {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 0),
              ObjectAnimator.ofFloat(target, "translationY", 0, target.getHeight() / 4));
        }
      };
    }
  },
  FADE_OUT_LEFT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 0),
              ObjectAnimator.ofFloat(target, "translationX", 0, -target.getWidth() / 4));
        }
      };
    }
  },
  FADE_OUT_RIGHT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 0),
              ObjectAnimator.ofFloat(target, "translationX", 0, target.getWidth() / 4));
        }
      };
    }
  },
  FADE_OUT_UP {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 0),
              ObjectAnimator.ofFloat(target, "translationY", 0, -target.getHeight() / 4));
        }
      };
    }
  },

  /* ------------------------------------------------------------------------------------------- */
  /* Flip
  /* ------------------------------------------------------------------------------------------- */

  FLIP_IN_X {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(
              ObjectAnimator.ofFloat(target, "rotationX", 90, -15, 15, 0),
              ObjectAnimator.ofFloat(target, "alpha", 0.25f, 0.5f, 0.75f, 1));
        }
      };
    }
  },
  FLIP_OUT_X {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "rotationX", 0, 90),
              ObjectAnimator.ofFloat(target, "alpha", 1, 0));
        }
      };
    }
  },
  FLIP_IN_Y {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(
              ObjectAnimator.ofFloat(target, "rotationY", 90, -15, 15, 0),
              ObjectAnimator.ofFloat(target, "alpha", 0.25f, 0.5f, 0.75f, 1));
        }
      };
    }
  },
  FLIP_OUT_Y {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "rotationY", 0, 90),
              ObjectAnimator.ofFloat(target, "alpha", 1, 0));
        }
      };
    }
  },

  /* ------------------------------------------------------------------------------------------- */
  /* Rotate
  /* ------------------------------------------------------------------------------------------- */

  ROTATE {
    @Override
    public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "rotation", 360, 0));
        }
      };
    }
  },
  ROTATE_IN {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "rotation", -200, 0),
              ObjectAnimator.ofFloat(target, "alpha", 0, 1));
        }
      };
    }
  },
  ROTATE_IN_DOWN_LEFT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          float x = target.getPaddingLeft();
          float y = target.getHeight() - target.getPaddingBottom();
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "rotation", -90, 0),
              ObjectAnimator.ofFloat(target, "alpha", 0, 1),
              ObjectAnimator.ofFloat(target, "pivotX", x, x),
              ObjectAnimator.ofFloat(target, "pivotY", y, y));
        }
      };
    }
  },
  ROTATE_IN_DOWN_RIGHT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          float x = target.getWidth() - target.getPaddingRight();
          float y = target.getHeight() - target.getPaddingBottom();
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "rotation", 90, 0),
              ObjectAnimator.ofFloat(target, "alpha", 0, 1),
              ObjectAnimator.ofFloat(target, "pivotX", x, x),
              ObjectAnimator.ofFloat(target, "pivotY", y, y));
        }
      };
    }
  },
  ROTATE_IN_UP_LEFT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          float x = target.getPaddingLeft();
          float y = target.getHeight() - target.getPaddingBottom();
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "rotation", 90, 0),
              ObjectAnimator.ofFloat(target, "alpha", 0, 1),
              ObjectAnimator.ofFloat(target, "pivotX", x, x),
              ObjectAnimator.ofFloat(target, "pivotY", y, y));
        }
      };
    }
  },
  ROTATE_IN_UP_RIGHT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          float x = target.getWidth() - target.getPaddingRight();
          float y = target.getHeight() - target.getPaddingBottom();
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "rotation", -90, 0),
              ObjectAnimator.ofFloat(target, "alpha", 0, 1),
              ObjectAnimator.ofFloat(target, "pivotX", x, x),
              ObjectAnimator.ofFloat(target, "pivotY", y, y));
        }
      };
    }
  },
  ROTATE_OUT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 0),
              ObjectAnimator.ofFloat(target, "rotation", 0, 200));
        }
      };
    }
  },
  ROTATE_OUT_DOWN_LEFT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          float x = target.getPaddingLeft();
          float y = target.getHeight() - target.getPaddingBottom();
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 0),
              ObjectAnimator.ofFloat(target, "rotation", 0, 90),
              ObjectAnimator.ofFloat(target, "pivotX", x, x),
              ObjectAnimator.ofFloat(target, "pivotY", y, y));
        }
      };
    }
  },
  ROTATE_OUT_DOWN_RIGHT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          float x = target.getWidth() - target.getPaddingRight();
          float y = target.getHeight() - target.getPaddingBottom();
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 0),
              ObjectAnimator.ofFloat(target, "rotation", 0, -90),
              ObjectAnimator.ofFloat(target, "pivotX", x, x),
              ObjectAnimator.ofFloat(target, "pivotY", y, y));
        }
      };
    }
  },
  ROTATE_OUT_UP_LEFT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          float x = target.getPaddingLeft();
          float y = target.getHeight() - target.getPaddingBottom();
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 0),
              ObjectAnimator.ofFloat(target, "rotation", 0, -90),
              ObjectAnimator.ofFloat(target, "pivotX", x, x),
              ObjectAnimator.ofFloat(target, "pivotY", y, y));
        }
      };
    }
  },
  ROTATE_OUT_UP_RIGHT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          float x = target.getWidth() - target.getPaddingRight();
          float y = target.getHeight() - target.getPaddingBottom();
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 0),
              ObjectAnimator.ofFloat(target, "rotation", 0, 90),
              ObjectAnimator.ofFloat(target, "pivotX", x, x),
              ObjectAnimator.ofFloat(target, "pivotY", y, y));
        }
      };
    }
  },

  /* ------------------------------------------------------------------------------------------- */
  /* Slide
  /* ------------------------------------------------------------------------------------------- */

  SLIDE_IN_LEFT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          ViewGroup parent = (ViewGroup) target.getParent();
          int distance = parent.getWidth() - target.getLeft();
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 0, 1),
              ObjectAnimator.ofFloat(target, "translationX", -distance, 0));
        }
      };
    }
  },
  SLIDE_IN_RIGHT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          ViewGroup parent = (ViewGroup) target.getParent();
          int distance = parent.getWidth() - target.getLeft();
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 0, 1),
              ObjectAnimator.ofFloat(target, "translationX", distance, 0));
        }
      };
    }
  },
  SLIDE_IN_UP {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          ViewGroup parent = (ViewGroup) target.getParent();
          int distance = parent.getHeight() - target.getTop();
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 0, 1),
              ObjectAnimator.ofFloat(target, "translationY", distance, 0));
        }
      };
    }
  },
  SLIDE_IN_DOWN {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          int distance = target.getTop() + target.getHeight();
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 0, 1),
              ObjectAnimator.ofFloat(target, "translationY", -distance, 0));
        }
      };
    }
  },
  SLIDE_OUT_LEFT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 0),
              ObjectAnimator.ofFloat(target, "translationX", 0, -target.getRight()));
        }
      };
    }
  },
  SLIDE_OUT_RIGHT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          ViewGroup parent = (ViewGroup) target.getParent();
          int distance = parent.getWidth() - target.getLeft();
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 0),
              ObjectAnimator.ofFloat(target, "translationX", 0, distance));
        }
      };
    }
  },
  SLIDE_OUT_UP {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 0),
              ObjectAnimator.ofFloat(target, "translationY", 0, -target.getBottom()));
        }
      };
    }
  },
  SLIDE_OUT_DOWN {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          ViewGroup parent = (ViewGroup) target.getParent();
          int distance = parent.getHeight() - target.getTop();
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 0),
              ObjectAnimator.ofFloat(target, "translationY", 0, distance));
        }
      };
    }
  },

  /* ------------------------------------------------------------------------------------------- */
  /* Zoom
  /* ------------------------------------------------------------------------------------------- */

  ZOOM_IN {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "scaleX", 0.45f, 1),
              ObjectAnimator.ofFloat(target, "scaleY", 0.45f, 1),
              ObjectAnimator.ofFloat(target, "alpha", 0, 1));
        }
      };
    }
  },
  ZOOM_IN_DOWN {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "scaleX", 0.1f, 0.475f, 1),
              ObjectAnimator.ofFloat(target, "scaleY", 0.1f, 0.475f, 1),
              ObjectAnimator.ofFloat(target, "translationY", -target.getBottom(), 60, 0),
              ObjectAnimator.ofFloat(target, "alpha", 0, 1, 1));
        }
      };
    }
  },
  ZOOM_IN_LEFT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(
              ObjectAnimator.ofFloat(target, "scaleX", 0.1f, 0.475f, 1),
              ObjectAnimator.ofFloat(target, "scaleY", 0.1f, 0.475f, 1),
              ObjectAnimator.ofFloat(target, "translationX",
                  target.getWidth() + target.getPaddingRight(), -48, 0),
              ObjectAnimator.ofFloat(target, "alpha", 0, 1, 1));
        }
      };
    }
  },
  ZOOM_IN_RIGHT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(
              ObjectAnimator.ofFloat(target, "scaleX", 0.1f, 0.475f, 1),
              ObjectAnimator.ofFloat(target, "scaleY", 0.1f, 0.475f, 1),
              ObjectAnimator.ofFloat(target, "translationX",
                  target.getWidth() + target.getPaddingRight(), -48, 0),
              ObjectAnimator.ofFloat(target, "alpha", 0, 1, 1));
        }
      };
    }
  },
  ZOOM_IN_UP {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          ViewGroup parent = (ViewGroup) target.getParent();
          int distance = parent.getHeight() - target.getTop();
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 0, 1, 1),
              ObjectAnimator.ofFloat(target, "scaleX", 0.1f, 0.475f, 1),
              ObjectAnimator.ofFloat(target, "scaleY", 0.1f, 0.475f, 1),
              ObjectAnimator.ofFloat(target, "translationY", distance, -60, 0));
        }
      };
    }
  },
  ZOOM_OUT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 0, 0),
              ObjectAnimator.ofFloat(target, "scaleX", 1, 0.3f, 0),
              ObjectAnimator.ofFloat(target, "scaleY", 1, 0.3f, 0));
        }
      };
    }
  },
  ZOOM_OUT_DOWN {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          ViewGroup parent = (ViewGroup) target.getParent();
          int distance = parent.getHeight() - target.getTop();
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 1, 0),
              ObjectAnimator.ofFloat(target, "scaleX", 1, 0.475f, 0.1f),
              ObjectAnimator.ofFloat(target, "scaleY", 1, 0.475f, 0.1f),
              ObjectAnimator.ofFloat(target, "translationY", 0, -60, distance));
        }
      };
    }
  },
  ZOOM_OUT_LEFT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 1, 0),
              ObjectAnimator.ofFloat(target, "scaleX", 1, 0.475f, 0.1f),
              ObjectAnimator.ofFloat(target, "scaleY", 1, 0.475f, 0.1f),
              ObjectAnimator.ofFloat(target, "translationX", 0, 42, -target.getRight()));
        }
      };
    }
  },
  ZOOM_OUT_RIGHT {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          ViewGroup parent = (ViewGroup) target.getParent();
          int distance = parent.getWidth() - parent.getLeft();
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 1, 0),
              ObjectAnimator.ofFloat(target, "scaleX", 1, 0.475f, 0.1f),
              ObjectAnimator.ofFloat(target, "scaleY", 1, 0.475f, 0.1f),
              ObjectAnimator.ofFloat(target, "translationX", 0, -42, distance));
        }
      };
    }
  },
  ZOOM_OUT_UP {
    @Override public SimpleAnimator getAnimator() {
      return new SimpleAnimator() {

        @Override protected void prepare(View target) {
          getAnimatorSet().playTogether(ObjectAnimator.ofFloat(target, "alpha", 1, 1, 0),
              ObjectAnimator.ofFloat(target, "scaleX", 1, 0.475f, 0.1f),
              ObjectAnimator.ofFloat(target, "scaleY", 1, 0.475f, 0.1f),
              ObjectAnimator.ofFloat(target, "translationY", 0, 60, -target.getBottom()));
        }
      };
    }
  };

  public abstract SimpleAnimator getAnimator();

  public Composer getComposer() {
    return new Composer(getAnimator());
  }

  public Controller playOn(View target) {
    return getComposer().playOn(target);
  }

  public static abstract class SimpleAnimator {

    private final AnimatorSet animatorSet = new AnimatorSet();
    private long duration = 1000;
    private View target;

    protected abstract void prepare(View target);

    public SimpleAnimator setStartDelay(long startDelay) {
      animatorSet.setStartDelay(startDelay);
      return this;
    }

    public SimpleAnimator addAnimatorListener(Animator.AnimatorListener listener) {
      animatorSet.addListener(listener);
      return this;
    }

    public SimpleAnimator setInterpolator(Interpolator interpolator) {
      animatorSet.setInterpolator(interpolator);
      return this;
    }

    public SimpleAnimator setDuration(long duration) {
      this.duration = duration;
      return this;
    }

    public SimpleAnimator setCallbacks(List<Animator.AnimatorListener> callbacks) {
      if (callbacks != null && !callbacks.isEmpty()) {
        for (Animator.AnimatorListener callback : callbacks) {
          animatorSet.addListener(callback);
        }
      }
      return this;
    }

    public SimpleAnimator setTarget(View target) {
      this.target = target;
      return this;
    }

    public void reset() {
      target.setAlpha(1);
      target.setScaleX(1);
      target.setScaleY(1);
      target.setTranslationX(0);
      target.setTranslationY(0);
      target.setRotation(0);
      target.setRotationY(0);
      target.setRotationX(0);
      target.setPivotX(target.getMeasuredWidth() / 2.0f);
      target.setPivotY(target.getMeasuredHeight() / 2.0f);
    }

    public Controller start() {
      reset();
      prepare(target);
      animatorSet.setDuration(duration);
      animatorSet.start();
      return new Controller(this);
    }

    public AnimatorSet getAnimatorSet() {
      return animatorSet;
    }

    public View getTarget() {
      return target;
    }

  }

  public static final class Composer {

    private final List<Animator.AnimatorListener> callbacks = new ArrayList<>();
    private final SimpleAnimator animator;
    private Interpolator interpolator;
    private long duration = 1000;
    private long delay;

    protected Composer(SimpleAnimator animator) {
      this.animator = animator;
    }

    public Composer duration(long duration) {
      this.duration = duration;
      return this;
    }

    public Composer delay(long delay) {
      this.delay = delay;
      return this;
    }

    public Composer interpolate(Interpolator interpolator) {
      this.interpolator = interpolator;
      return this;
    }

    public Composer withListener(Animator.AnimatorListener listener) {
      callbacks.add(listener);
      return this;
    }

    public Composer hideOnFinished() {
      return onEnd(new AnimatorCallback() {

        @Override public void call(SimpleAnimator animator) {
          animator.getTarget().setVisibility(View.GONE);
        }
      });
    }

    public Composer showOnStart() {
      return onStart(new AnimatorCallback() {

        @Override public void call(SimpleAnimator animator) {
          animator.getTarget().setVisibility(View.VISIBLE);
        }
      });
    }

    public Composer onStart(final AnimatorCallback callback) {
      callbacks.add(new EmptyAnimatorListener() {

        @Override public void onAnimationStart(Animator animation) {
          callback.call(animator);
        }
      });
      return this;
    }

    public Composer onEnd(final AnimatorCallback callback) {
      callbacks.add(new EmptyAnimatorListener() {

        @Override public void onAnimationEnd(Animator animation) {
          callback.call(animator);
        }
      });
      return this;
    }

    public Composer onCancel(final AnimatorCallback callback) {
      callbacks.add(new EmptyAnimatorListener() {

        @Override public void onAnimationCancel(Animator animation) {
          callback.call(animator);
        }
      });
      return this;
    }

    public Composer onRepeat(final AnimatorCallback callback) {
      callbacks.add(new EmptyAnimatorListener() {

        @Override public void onAnimationRepeat(Animator animation) {
          callback.call(animator);
        }
      });
      return this;
    }

    public Controller playOn(View target) {
      return animator.setTarget(target)
          .setDuration(duration)
          .setInterpolator(interpolator)
          .setStartDelay(delay)
          .setCallbacks(callbacks)
          .start();
    }

  }

  public static final class Controller {

    private final SimpleAnimator animator;

    private Controller(SimpleAnimator animator) {
      this.animator = animator;
    }

    public boolean isStarted() {
      return animator.getAnimatorSet().isStarted();
    }

    public boolean isRunning() {
      return animator.getAnimatorSet().isRunning();
    }

    public void stop(boolean reset) {
      animator.getAnimatorSet().cancel();
      if (reset) {
        animator.reset();
      }
    }

  }

  private static class EmptyAnimatorListener implements Animator.AnimatorListener {

    @Override public void onAnimationStart(Animator animation) {
    }

    @Override public void onAnimationEnd(Animator animation) {
    }

    @Override public void onAnimationCancel(Animator animation) {
    }

    @Override public void onAnimationRepeat(Animator animation) {
    }
  }

  public interface AnimatorCallback {

    void call(SimpleAnimator animator);
  }

}

以上是关于java Android缓动功能。动画集合,有助于简化动画。的主要内容,如果未能解决你的问题,请参考以下文章

如何构建自定义 jQuery 缓动/弹跳动画?

最好远离另一个进程动画窗口的位置,正弦缓动?

用缓动函数模拟物理动画

如何使用 Core Animation 创建自定义缓动功能?

动画: 缓动动画

定时器缓动动画