package com.marshalchen.common.uimodule.easyandroidanimations; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.view.View; import android.view.ViewGroup; import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.FrameLayout; /** * This animation causes the view to slide out underneath to its own borders. On * animation end, the view is restored to its original state and is set to * <code>View.INVISIBLE</code>. * * @author SiYao * */ public class SlideOutUnderneathAnimation extends Animation { int direction; TimeInterpolator interpolator; long duration; AnimationListener listener; ValueAnimator slideAnim; /** * This animation causes the view to slide out underneath to its own * borders. On animation end, the view is restored to its original state and * is set to <code>View.INVISIBLE</code>. * * @param view * The view to be animated. */ public SlideOutUnderneathAnimation(View view) { this.view = view; direction = DIRECTION_LEFT; interpolator = new AccelerateDecelerateInterpolator(); duration = DURATION_LONG; listener = null; } @Override public void animate() { final ViewGroup parentView = (ViewGroup) view.getParent(); final FrameLayout slideOutFrame = new FrameLayout(view.getContext()); final int positionView = parentView.indexOfChild(view); slideOutFrame.setLayoutParams(view.getLayoutParams()); slideOutFrame.setClipChildren(true); parentView.removeView(view); slideOutFrame.addView(view); parentView.addView(slideOutFrame, positionView); switch (direction) { case DIRECTION_LEFT: slideAnim = ObjectAnimator.ofFloat(view, View.TRANSLATION_X, view.getTranslationX() - view.getWidth()); break; case DIRECTION_RIGHT: slideAnim = ObjectAnimator.ofFloat(view, View.TRANSLATION_X, view.getTranslationX() + view.getWidth()); break; case DIRECTION_UP: slideAnim = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, view.getTranslationY() - view.getHeight()); break; case DIRECTION_DOWN: slideAnim = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, view.getTranslationY() + view.getHeight()); break; default: break; } AnimatorSet slideSet = new AnimatorSet(); slideSet.play(slideAnim); slideSet.setInterpolator(interpolator); slideSet.setDuration(duration); slideSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { view.setVisibility(View.INVISIBLE); slideAnim.reverse(); slideOutFrame.removeAllViews(); parentView.removeView(slideOutFrame); parentView.addView(view, positionView); if (getListener() != null) { getListener().onAnimationEnd( SlideOutUnderneathAnimation.this); } } }); slideSet.start(); } /** * The available directions to slide in from are <code>DIRECTION_LEFT</code> * , <code>DIRECTION_RIGHT</code>, <code>DIRECTION_TOP</code> and * <code>DIRECTION_BOTTOM</code>. * * @return The direction to slide the view out to. * @see Animation */ public int getDirection() { return direction; } /** * The available directions to slide in from are <code>DIRECTION_LEFT</code> * , <code>DIRECTION_RIGHT</code>, <code>DIRECTION_TOP</code> and * <code>DIRECTION_BOTTOM</code>. * * @param direction * The direction to set to slide the view out to. * @return This object, allowing calls to methods in this class to be * chained. * @see Animation */ public SlideOutUnderneathAnimation setDirection(int direction) { this.direction = direction; return this; } /** * @return The interpolator of the entire animation. */ public TimeInterpolator getInterpolator() { return interpolator; } /** * @param interpolator * The interpolator of the entire animation to set. */ public SlideOutUnderneathAnimation setInterpolator( TimeInterpolator interpolator) { this.interpolator = interpolator; return this; } /** * @return The duration of the entire animation. */ public long getDuration() { return duration; } /** * @param duration * The duration of the entire animation to set. * @return This object, allowing calls to methods in this class to be * chained. */ public SlideOutUnderneathAnimation setDuration(long duration) { this.duration = duration; return this; } /** * @return The listener for the end of the animation. */ public AnimationListener getListener() { return listener; } /** * @param listener * The listener to set for the end of the animation. * @return This object, allowing calls to methods in this class to be * chained. */ public SlideOutUnderneathAnimation setListener(AnimationListener listener) { this.listener = listener; return this; } }