package net.simonvt.messagebar;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.TextView;
import java.util.LinkedList;
public class MessageBar {
public interface OnMessageClickListener {
void onMessageClick(Parcelable token);
}
private static final String STATE_MESSAGES = "net.simonvt.messagebar.MessageBar.messages";
private static final String STATE_CURRENT_MESSAGE = "net.simonvt.messagebar.MessageBar.currentMessage";
private static final int ANIMATION_DURATION = 600;
private static final int HIDE_DELAY = 5000;
private View mContainer;
private TextView mTextView;
private TextView mButton;
private LinkedList<Message> mMessages = new LinkedList<Message>();
private Message mCurrentMessage;
private boolean mShowing;
private OnMessageClickListener mClickListener;
private Handler mHandler;
private AlphaAnimation mFadeInAnimation;
private AlphaAnimation mFadeOutAnimation;
public MessageBar(Activity activity) {
ViewGroup container = (ViewGroup) activity.findViewById(android.R.id.content);
View v = activity.getLayoutInflater().inflate(R.layout.mb__messagebar, container);
init(v);
}
public MessageBar(View v) {
init(v);
}
private void init(View v) {
mContainer = v.findViewById(R.id.mbContainer);
mContainer.setVisibility(View.GONE);
mTextView = (TextView) v.findViewById(R.id.mbMessage);
mButton = (TextView) v.findViewById(R.id.mbButton);
mButton.setOnClickListener(mButtonListener);
mFadeInAnimation = new AlphaAnimation(0.0f, 1.0f);
mFadeOutAnimation = new AlphaAnimation(1.0f, 0.0f);
mFadeOutAnimation.setDuration(ANIMATION_DURATION);
mFadeOutAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
Message nextMessage = mMessages.poll();
if (nextMessage != null) {
show(nextMessage);
} else {
mCurrentMessage = null;
mContainer.setVisibility(View.GONE);
mShowing = false;
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
mHandler = new Handler();
}
public void show(String message) {
show(message, null);
}
public void show(String message, String actionMessage) {
show(message, actionMessage, 0);
}
public void show(String message, String actionMessage, int actionIcon) {
show(message, actionMessage, actionIcon, null);
}
public void show(String message, String actionMessage, int actionIcon, Parcelable token) {
Message m = new Message(message, actionMessage, actionIcon, token);
if (mShowing) {
mMessages.add(m);
} else {
show(m);
}
}
private void show(Message message) {
show(message, false);
}
private void show(Message message, boolean immediately) {
mShowing = true;
mContainer.setVisibility(View.VISIBLE);
mCurrentMessage = message;
mTextView.setText(message.mMessage);
if (message.mActionMessage != null) {
mTextView.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
mButton.setVisibility(View.VISIBLE);
mButton.setText(message.mActionMessage);
mButton.setCompoundDrawablesWithIntrinsicBounds(message.mActionIcon, 0, 0, 0);
} else {
mTextView.setGravity(Gravity.CENTER);
mButton.setVisibility(View.GONE);
}
if (immediately) {
mFadeInAnimation.setDuration(0);
} else {
mFadeInAnimation.setDuration(ANIMATION_DURATION);
}
mContainer.startAnimation(mFadeInAnimation);
mHandler.postDelayed(mHideRunnable, HIDE_DELAY);
}
private final View.OnClickListener mButtonListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mClickListener != null && mCurrentMessage != null) {
mClickListener.onMessageClick(mCurrentMessage.mToken);
mCurrentMessage = null;
mHandler.removeCallbacks(mHideRunnable);
mHideRunnable.run();
}
}
};
public void setOnClickListener(OnMessageClickListener listener) {
mClickListener = listener;
}
public void clear() {
mMessages.clear();
mHideRunnable.run();
}
private final Runnable mHideRunnable = new Runnable() {
@Override
public void run() {
mContainer.startAnimation(mFadeOutAnimation);
}
};
public void onRestoreInstanceState(Bundle state) {
Message currentMessage = state.getParcelable(STATE_CURRENT_MESSAGE);
if (currentMessage != null) {
show(currentMessage, true);
Parcelable[] messages = state.getParcelableArray(STATE_MESSAGES);
for (Parcelable p : messages) {
mMessages.add((Message) p);
}
}
}
public Bundle onSaveInstanceState() {
Bundle b = new Bundle();
b.putParcelable(STATE_CURRENT_MESSAGE, mCurrentMessage);
final int count = mMessages.size();
final Message[] messages = new Message[count];
int i = 0;
for (Message message : mMessages) {
messages[i++] = message;
}
b.putParcelableArray(STATE_MESSAGES, messages);
return b;
}
private static class Message implements Parcelable {
final String mMessage;
final String mActionMessage;
final int mActionIcon;
final Parcelable mToken;
public Message(String message, String actionMessage, int actionIcon, Parcelable token) {
mMessage = message;
mActionMessage = actionMessage;
mActionIcon = actionIcon;
mToken = token;
}
public Message(Parcel p) {
mMessage = p.readString();
mActionMessage = p.readString();
mActionIcon = p.readInt();
mToken = p.readParcelable(getClass().getClassLoader());
}
public void writeToParcel(Parcel out, int flags) {
out.writeString(mMessage);
out.writeString(mActionMessage);
out.writeInt(mActionIcon);
out.writeParcelable(mToken, 0);
}
public int describeContents() {
return 0;
}
public static final Parcelable.Creator<Message> CREATOR = new Parcelable.Creator<Message>() {
public Message createFromParcel(Parcel in) {
return new Message(in);
}
public Message[] newArray(int size) {
return new Message[size];
}
};
}
}