@Override
 public void prepare(View target) {
   float x =
       (target.getWidth() - target.getPaddingLeft() - target.getPaddingRight()) / 2
           + target.getPaddingLeft();
   float y = target.getHeight() - target.getPaddingBottom();
   getAnimatorAgent()
       .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));
 }
  protected ObjectAnimator animateAlpha(final View view, final boolean fadeIn) {
    final ObjectAnimator anim =
        ObjectAnimator.ofFloat(view, "alpha", fadeIn ? new float[] {0f, 1f} : new float[] {1f, 0f});

    anim.setDuration((long) (ALPHA_ANIM_DURATION * animationDurationFactor));

    return anim;
  }
 @Override
 protected void prepare(View target) {
   getAnimatorAgent()
       .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()));
 }
  protected ObjectAnimator animateY(
      final View view, final float oldY, final float newY, final float durationUnit) {
    final int duration = getDuration(oldY, newY, durationUnit);

    final ObjectAnimator anim =
        ObjectAnimator.ofFloat(AnimatorProxy.wrap(view), "translationY", oldY - newY, 0);

    final int finalDuration = Math.min(Math.max(duration, MIN_ANIM_DURATION), MAX_ANIM_DURATION);

    anim.setDuration((long) (finalDuration * animationDurationFactor));
    anim.setInterpolator(translateInterpolater);

    return anim;
  }
  /** Animate items that just appeared and items that move within the screen. */
  private void animatePostLayout(final float durationUnit) {

    final AnimatorSet animatorSet = new AnimatorSet();

    for (int i = 0; i < getChildCount(); i++) {
      final View child = getChildAt(i);
      final long id = getItemIdAtPosition(getFirstVisiblePosition() + i);

      ObjectAnimator anim = null;

      ViewHelper.setAlpha(child, 1f);

      if (yMap.containsKey(id)) {
        // moved within visible area

        // log("Moved within visible area id: " + id);
        final float oldY = yMap.remove(id);
        final float newY = ViewHelper.getY(child);

        if (oldY != newY) {
          anim = animateY(child, oldY, newY, durationUnit);
        }

      } else {
        // moved into visible area or new

        if (beforeVisible.contains(id)) {
          // moved from top
          final float newY = ViewHelper.getY(child);
          final float oldY = -child.getHeight();

          anim = animateY(child, oldY, newY, durationUnit);
        } else if (afterVisible.contains(id)) {
          // moved from bottom
          final float newY = ViewHelper.getY(child);
          final float oldY = getHeight();

          anim = animateY(child, oldY, newY, durationUnit);
        } else {
          // entirely new
          ViewHelper.setAlpha(child, 0f);

          anim = animateAlpha(child, true);
          anim.setStartDelay(MIN_ANIM_DURATION);
        }
      }

      if (anim != null) {
        animatorSet.play(anim);
      }
    }

    animatorSet.addListener(
        new AnimatorListenerAdapter() {
          @Override
          public void onAnimationEnd(final Animator animation) {
            finishAnimation();
          };
        });

    animatorSet.start();
  }
  /** Animate items that are deleted entirely and items that move out of bounds. */
  private void animatePreLayout(
      final float durationUnit, final Animator.AnimatorListener listener) {
    final AnimatorSet animatorSet = new AnimatorSet();

    final int firstVisiblePosition = getFirstVisiblePosition();
    final int childCount = getChildCount();

    for (final Iterator<Entry<Long, Float>> iter = yMap.entrySet().iterator(); iter.hasNext(); ) {
      final Entry<Long, Float> entry = iter.next();

      final long id = entry.getKey();
      final int oldPos = positionMap.get(id);
      final View child = getChildAt(oldPos - firstVisiblePosition);
      final int newPos = getPositionForId(id);

      // fade out items that disappear
      if (newPos == -1) {
        final ObjectAnimator anim = animateAlpha(child, false);
        animatorSet.play(anim);

        iter.remove();
        positionMap.remove(id);
        continue;
      }

      // translate items that move out of bounds
      if (newPos < firstVisiblePosition || newPos > firstVisiblePosition + childCount) {
        final float offset;

        if (newPos < firstVisiblePosition) {
          offset = -getHeight();
        } else {
          offset = getHeight();
        }

        final AnimatorProxy proxy = AnimatorProxy.wrap(child);
        final ObjectAnimator anim = ObjectAnimator.ofFloat(proxy, "translationY", 0f, offset);

        final int finalDuration = getDuration(0, getHeight() / 2, durationUnit);

        anim.setInterpolator(new AccelerateInterpolator());
        anim.setDuration((long) (finalDuration * animationDurationFactor));

        animatorSet.addListener(
            new AnimatorListenerAdapter() {
              @Override
              public void onAnimationEnd(final Animator animation) {
                child.post(
                    new Runnable() {

                      @Override
                      public void run() {
                        proxy.setTranslationY(0f);
                      }
                    });
              }
            });
        animatorSet.play(anim);

        iter.remove();
        positionMap.remove(id);
        continue;
      }
    }

    if (!animatorSet.getChildAnimations().isEmpty()) {
      animatorSet.addListener(listener);
      animatorSet.start();
    } else {
      listener.onAnimationEnd(animatorSet);
    }
  }