Skip to content

Instantly share code, notes, and snippets.

@vincent1086
Last active August 29, 2016 09:38
Show Gist options
  • Save vincent1086/cbd5fd86ac674a237af1e49ec10a4faf to your computer and use it in GitHub Desktop.
Save vincent1086/cbd5fd86ac674a237af1e49ec10a4faf to your computer and use it in GitHub Desktop.
Android - Sliding Custom View
/*
* <declare-styleable name="slideViewSyle">
* <attr name="direction" format="enum">
* <enum name="top" value="0"/>
* <enum name="bottom" value="1" />
* <enum name="left" value="2" />
* <enum name="right" value="3" />
* </attr>
* </declare-styleable>
*
*/
public class SlideView extends RelativeLayout {
private final static String TAG = "SlideView";
private boolean isVisible;
private Runnable delayRunnable;
private int direction = 0;
private int height = -1;
private ObjectAnimator objectAnimator;
public SlideView(Context context) {
super(context);
}
public SlideView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize(context, attrs);
}
public SlideView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize(context, attrs);
}
private void initialize(Context context, AttributeSet attrs){
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.slideViewSyle);
if(attrs != null){
direction = a.getInteger(R.styleable.slideViewSyle_direction, 0);
}
a.recycle();
}
public void show(final boolean animate, int delay){
delayRunnable = new Runnable(){
@Override public void run() {
toggle(true, animate, false);
}
};
postDelayed(delayRunnable, delay);
}
public void show(boolean animate){
toggle(true, animate, false);
}
public void hide(boolean animate){
if(delayRunnable != null) removeCallbacks(delayRunnable);
toggle(false, animate, false);
}
public boolean isVisible(){
return isVisible;
}
private void toggle(final boolean visible, final boolean animate, final boolean initialize){
if(height == 0 || initialize) {
//DebugUtils.i("-> initialize");
final ViewTreeObserver observer = getViewTreeObserver();
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
height = getHeight();
toggle(visible, animate, true);
getViewTreeObserver().removeOnPreDrawListener(this);
return false;
}
});
}else {
//DebugUtils.i("-> Setup Animation");
if (isVisible != visible) {
//DebugUtils.i("-> Setup State " + visible);
isVisible = visible;
int translationY = 0;
int translationX = 0;
boolean isUp;
switch (direction) {
case 0:
translationY = visible ? 0 : -(getMeasuredHeight() + getPaddingTop());
break;
case 1:
translationY = visible ? 0 : getMeasuredHeight() + getPaddingTop();
break;
case 2:
translationX = visible ? 0 : -(getMeasuredWidth() + getPaddingLeft());
break;
case 3:
translationX = visible ? 0 : getMeasuredWidth() + getPaddingRight();
break;
}
isUp = direction == 0 || direction == 1;
if (animate) {
if(objectAnimator != null && (objectAnimator.isStarted() || objectAnimator.isRunning())) objectAnimator.cancel();
objectAnimator = ObjectAnimator.ofFloat(this, isUp ? "translationY" : "translationX", isUp ? translationY : translationX);
objectAnimator.setDuration(500);
objectAnimator.setInterpolator(new DecelerateInterpolator(4f));
objectAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
if(!isVisible) setVisibility(View.GONE);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
objectAnimator.start();
} else {
if (isUp) {
ViewHelper.setTranslationY(this, translationY);
} else {
ViewHelper.setTranslationX(this, translationX);
}
setVisibility(View.INVISIBLE);
}
// On pre-Honeycomb a translated view is still clickable, so we need to disable clicks manually
if (!AppUtils.hasHoneycomb()) {
setClickable(visible);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment