/**
* Copyright 2014 John Persano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.github.johnpersano.supertoasts;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.WindowManager;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
/* Manages the life of a SuperToast. Initially copied from the Crouton library */
public class ManagerSuperToast extends Handler {
@SuppressWarnings("UnusedDeclaration")
private static final String TAG = "ManagerSuperToast";
/* Potential messages for the handler to send **/
private static final class Messages {
/* Hexadecimal numbers that represent acronyms for the operation **/
private static final int DISPLAY_SUPERTOAST = 0x445354;
private static final int ADD_SUPERTOAST = 0x415354;
private static final int REMOVE_SUPERTOAST = 0x525354;
}
private static ManagerSuperToast mManagerSuperToast;
private final Queue<SuperToast> mQueue;
/* Private method to create a new list if the manager is being initialized */
private ManagerSuperToast() {
mQueue = new LinkedBlockingQueue<>();
}
/* Singleton method to ensure all SuperToasts are passed through the same manager */
static synchronized ManagerSuperToast getInstance() {
if (mManagerSuperToast != null) {
return mManagerSuperToast;
} else {
mManagerSuperToast = new ManagerSuperToast();
return mManagerSuperToast;
}
}
/* Add SuperToast to queue and try to show it */
void add(SuperToast superToast) {
/* Add SuperToast to queue and try to show it */
mQueue.add(superToast);
this.showNextSuperToast();
}
/* Shows the next SuperToast in the list */
private void showNextSuperToast() {
if (mQueue.isEmpty()) {
/* There is no SuperToast to display next */
return;
}
/* Get next SuperToast in the queue */
final SuperToast superToast = mQueue.peek();
/* Show SuperToast if none are showing (not sure why this works but it does) */
if (!superToast.isShowing()) {
final Message message = obtainMessage(Messages.ADD_SUPERTOAST);
message.obj = superToast;
sendMessage(message);
} else {
sendMessageDelayed(superToast, Messages.DISPLAY_SUPERTOAST,
getDuration(superToast));
}
}
/* Show/dismiss a SuperToast after a specific duration */
private void sendMessageDelayed(SuperToast superToast, final int messageId, final long delay) {
Message message = obtainMessage(messageId);
message.obj = superToast;
sendMessageDelayed(message, delay);
}
/* Get duration and add one second to compensate for show/hide animations */
private long getDuration(SuperToast superToast) {
long duration = superToast.getDuration();
duration += 1000;
return duration;
}
@Override
public void handleMessage(Message message) {
final SuperToast superToast = (SuperToast)
message.obj;
switch (message.what) {
case Messages.DISPLAY_SUPERTOAST:
showNextSuperToast();
break;
case Messages.ADD_SUPERTOAST:
displaySuperToast(superToast);
break;
case Messages.REMOVE_SUPERTOAST:
removeSuperToast(superToast);
break;
default: {
super.handleMessage(message);
break;
}
}
}
/* Displays a SuperToast */
private void displaySuperToast(SuperToast superToast) {
if (superToast.isShowing()) {
/* If the SuperToast is already showing do not show again */
return;
}
final WindowManager windowManager = superToast
.getWindowManager();
final View toastView = superToast.getView();
final WindowManager.LayoutParams params = superToast
.getWindowManagerParams();
if(windowManager != null) {
windowManager.addView(toastView, params);
}
sendMessageDelayed(superToast, Messages.REMOVE_SUPERTOAST,
superToast.getDuration() + 500);
}
/* Hide and remove the SuperToast */
void removeSuperToast(SuperToast superToast) {
final WindowManager windowManager = superToast
.getWindowManager();
final View toastView = superToast.getView();
if (windowManager != null) {
mQueue.poll();
windowManager.removeView(toastView);
sendMessageDelayed(superToast,
Messages.DISPLAY_SUPERTOAST, 500);
if(superToast.getOnDismissListener() != null) {
superToast.getOnDismissListener().onDismiss(superToast.getView());
}
}
}
/* Cancels/removes all showing pending SuperToasts */
void cancelAllSuperToasts() {
removeMessages(Messages.ADD_SUPERTOAST);
removeMessages(Messages.DISPLAY_SUPERTOAST);
removeMessages(Messages.REMOVE_SUPERTOAST);
for (SuperToast superToast : mQueue) {
if (superToast.isShowing()) {
superToast.getWindowManager().removeView(
superToast.getView());
}
}
mQueue.clear();
}
}