package com.hotbitmapgg.moequest.notice; import android.animation.Animator; import android.animation.ObjectAnimator; import android.app.NotificationManager; import android.content.Context; import android.os.Build; import android.view.Gravity; import android.view.WindowManager; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Queue; public class HeadsUpManager { private WindowManager wmOne; private FloatView floatView; private Queue<HeadsUp> msgQueue; private static HeadsUpManager manager; private Context context; private boolean isPolling = false; private Map<Integer, HeadsUp> map; private NotificationManager notificationManager = null; public static HeadsUpManager getInstant(Context c) { if (manager == null) { manager = new HeadsUpManager(c); } return manager; } private HeadsUpManager(Context context) { this.context = context; map = new HashMap<Integer, HeadsUp>(); msgQueue = new LinkedList<HeadsUp>(); wmOne = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); notificationManager = (NotificationManager) context.getSystemService( Context.NOTIFICATION_SERVICE); } public synchronized void notify(HeadsUp headsUp) { if (map.containsKey(headsUp.getCode())) { msgQueue.remove(map.get(headsUp.getCode())); } map.put(headsUp.getCode(), headsUp); msgQueue.add(headsUp); if (!isPolling) { poll(); } } public synchronized void notify(int code, HeadsUp headsUp) { headsUp.setCode(code); notify(headsUp); } public synchronized void cancel(HeadsUp headsUp) { cancel(headsUp.getCode()); } private synchronized void poll() { if (!msgQueue.isEmpty()) { HeadsUp headsUp = msgQueue.poll(); map.remove(headsUp.getCode()); if (Build.VERSION.SDK_INT < 21 || headsUp.getCustomView() != null || !headsUp.isActivateStatusBar()) { isPolling = true; show(headsUp); } else { //当 系统是 lollipop 以上,并且没有自定义布局以后,调用系统自己的 notification isPolling = false; notificationManager.notify(headsUp.getCode(), headsUp.getBuilder().setIcon(headsUp.getIcon()).build()); } } else { isPolling = false; } } private void show(HeadsUp headsUp) { floatView = new FloatView(context, 20); WindowManager.LayoutParams params = FloatView.winParams; params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR; params.width = WindowManager.LayoutParams.MATCH_PARENT; params.height = WindowManager.LayoutParams.WRAP_CONTENT; params.format = -3; params.gravity = Gravity.CENTER | Gravity.TOP; params.x = floatView.originalLeft; params.y = 0; params.alpha = 1f; wmOne.addView(floatView, params); ObjectAnimator a = ObjectAnimator.ofFloat(floatView.rootView, "translationY", -700, 0); a.setDuration(600); a.start(); floatView.setNotification(headsUp); if (headsUp.getNotification() != null) { notificationManager.notify(headsUp.getCode(), headsUp.getNotification()); } } public void cancel() { if (floatView != null && floatView.getParent() != null) { floatView.cancel(); } } protected void dismiss() { if (floatView.getParent() != null) { wmOne.removeView(floatView); floatView.postDelayed(new Runnable() { @Override public void run() { poll(); } }, 1000); } } protected void animDismiss() { if (floatView != null && floatView.getParent() != null) { ObjectAnimator a = ObjectAnimator.ofFloat(floatView.rootView, "translationY", 0, -700); a.setDuration(700); a.start(); a.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animator) { } @Override public void onAnimationEnd(Animator animator) { dismiss(); } @Override public void onAnimationCancel(Animator animator) { } @Override public void onAnimationRepeat(Animator animator) { } }); } } protected void animDismiss(HeadsUp headsUp) { if (floatView.getHeadsUp().getCode() == headsUp.getCode()) { animDismiss(); } } protected void silencerNotify(HeadsUp headsUp) { if (headsUp.getSilencerNotification() != null) { notificationManager.notify(headsUp.getCode(), headsUp.getSilencerNotification()); } } public void cancel(int code) { if (map.containsKey(code)) { msgQueue.remove(map.get(code)); } if (floatView != null && floatView.getHeadsUp().getCode() == code) { animDismiss(); } } public void close() { cancelAll(); manager = null; } public void cancelAll() { msgQueue.clear(); if (floatView != null && floatView.getParent() != null) { animDismiss(); } } }