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;
}
}