package com.malmstein.yahnac.views;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.malmstein.yahnac.R;
import com.novoda.notils.caster.Views;
import com.novoda.notils.exception.DeveloperError;
public class SnackBarView extends LinearLayout {
public static final int DEFAULT_BG_COLOR = 0xEA333333;
private TextView croutonText;
private TextView croutonUndo;
private OnClickListener onUndoClickListener;
private CroutonAutoHideRunnable croutonAutoHideRunnable;
private long dismissAnimationDuration;
private LinearLayout croutonContainer;
public SnackBarView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SnackBarView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setOrientation(VERTICAL);
setVisibility(INVISIBLE);
croutonAutoHideRunnable = new CroutonAutoHideRunnable();
}
@Override
public void setOrientation(int orientation) {
if (orientation != VERTICAL) {
throw new DeveloperError("CroutonView supports only vertical orientation");
}
super.setOrientation(orientation);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
layoutInflater.inflate(R.layout.merge_snackbar, this, true);
croutonContainer = Views.findById(this, R.id.crouton_container);
croutonContainer.setBackgroundColor(DEFAULT_BG_COLOR);
croutonText = (TextView) findViewById(R.id.crouton_text);
croutonText.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
hideCrouton(true);
}
});
croutonUndo = (TextView) findViewById(R.id.crouton_undo);
croutonUndo.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (onUndoClickListener != null) {
onUndoClickListener.onClick(SnackBarView.this);
}
}
});
}
@Override
public void setBackgroundColor(int color) {
croutonContainer.setBackgroundColor(color);
}
@Override
public void setBackgroundResource(int resid) {
croutonContainer.setBackgroundResource(resid);
}
@Override
public void setBackground(Drawable background) {
croutonContainer.setBackground(background);
}
@Override
public void setBackgroundDrawable(Drawable background) {
croutonContainer.setBackgroundDrawable(background);
}
public ShowCroutonAction showSnackBar(CharSequence message) {
return new ShowCroutonAction(this, message);
}
public void hideCrouton() {
hideCrouton(true);
}
public void hideCrouton(boolean animate) {
cancelPendingCroutonAutoHide();
if (getVisibility() != INVISIBLE) {
if (animate) {
animateCroutonDisappearance(dismissAnimationDuration);
} else {
setVisibility(INVISIBLE);
}
}
}
private void animateCroutonAppearance(long animationDuration) {
cancelPendingCroutonAutoHide();
setVisibility(VISIBLE);
setTranslationY(getHeight());
animate()
.translationY(0f)
.setInterpolator(new DecelerateInterpolator())
.setDuration(animationDuration)
.withEndAction(new Runnable() {
@Override
public void run() {
setEnabled(true);
}
});
}
private void scheduleAutoHideIfNeeded(long autohideDelay) {
if (autohideDelay > 0) {
postDelayed(croutonAutoHideRunnable, autohideDelay);
}
}
private void cancelPendingCroutonAutoHide() {
removeCallbacks(croutonAutoHideRunnable);
}
private void animateCroutonDisappearance(long animationDuration) {
cancelPendingCroutonAutoHide();
setTranslationY(0f);
setEnabled(false);
animate()
.translationY(getHeight())
.setInterpolator(new AccelerateInterpolator())
.setDuration(animationDuration)
.withEndAction(new Runnable() {
@Override
public void run() {
setVisibility(INVISIBLE);
}
});
}
public static class ShowCroutonAction {
public static final long DEFAULT_ANIMATION_DURATION_MS = 500;
public static final long DEFAULT_AUTOHIDE_DELAY_MS = 3500;
private static final int DISMISS_ANIMATION_SPEEDUP_FACTOR = 3;
protected SnackBarView crouton;
protected long animationDuration;
protected long autohideDelay;
private long dismissAnimationDuration;
protected ShowCroutonAction(SnackBarView crouton, CharSequence message) {
crouton.croutonText.setText(message);
crouton.croutonText.setBackground(null);
crouton.croutonUndo.setVisibility(View.GONE);
crouton.croutonContainer.setBackgroundColor(DEFAULT_BG_COLOR);
this.crouton = crouton;
this.animationDuration = DEFAULT_ANIMATION_DURATION_MS;
this.autohideDelay = DEFAULT_AUTOHIDE_DELAY_MS;
}
private static int computeBackgroundColor(int baseColor, int alpha) {
return Color.argb(alpha, getRed(baseColor), getGreen(baseColor), getBlue(baseColor));
}
private static int getRed(int startColor) {
return (startColor >> 16) & 0xFF;
}
private static int getGreen(int startColor) {
return (startColor >> 8) & 0xFF;
}
private static int getBlue(int startColor) {
return startColor & 0xFF;
}
public ShowCroutonAction withBackgroundColor(int baseColor, int alpha) {
crouton.croutonContainer.setBackgroundColor(computeBackgroundColor(baseColor, alpha));
return this;
}
public ShowCroutonAction withUndoClickListener(OnClickListener l) {
crouton.croutonUndo.setVisibility(View.VISIBLE);
crouton.onUndoClickListener = l;
return this;
}
public ShowCroutonAction withCustomTextClickListener(OnClickListener l, int actionResource) {
crouton.croutonUndo.setText(actionResource);
crouton.croutonUndo.setVisibility(View.VISIBLE);
crouton.onUndoClickListener = l;
return this;
}
public ShowCroutonAction withAnimationDuration(long duration) {
this.animationDuration = duration;
return this;
}
public void animating() {
show(true);
}
private void show(boolean animate) {
crouton.cancelPendingCroutonAutoHide();
updateDismissAnimationDuration();
crouton.dismissAnimationDuration = dismissAnimationDuration;
if (crouton.getVisibility() != VISIBLE) {
if (animate) {
crouton.animateCroutonAppearance(animationDuration);
} else {
crouton.setVisibility(VISIBLE);
}
}
crouton.scheduleAutoHideIfNeeded(autohideDelay);
}
private void updateDismissAnimationDuration() {
if (dismissAnimationDuration <= 0) {
dismissAnimationDuration = animationDuration / DISMISS_ANIMATION_SPEEDUP_FACTOR;
}
}
}
private class CroutonAutoHideRunnable implements Runnable {
@Override
public void run() {
animateCroutonDisappearance(dismissAnimationDuration);
}
}
}