package hk.hku.cs.srli.widget.util; import android.app.Activity; import android.content.Context; import android.graphics.Rect; import android.os.Handler; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import hk.hku.cs.srli.widget.R; import hk.hku.cs.srli.widget.Tooltip; public class TooltipManager { public static final long LONG_DELAY = 3500; // 3.5 seconds public static final long SHORT_DELAY = 2000; // 2 seconds private static TooltipManager instance = null; private final Handler handler; private Tooltip tooltip; private Context context; // Singleton object. private TooltipManager(Context context) { this.context = context; this.handler = new Handler(); } private static TooltipManager getInstance(Context context) { if (instance == null) { instance = new TooltipManager(context); } else if (instance.context != context) { instance.resetContext(context); } return instance; } public static Tooltip show(View view, CharSequence text) { return show(view, text, 0, 0); } public static Tooltip show(View view, CharSequence text, int xoffset, int yoffset) { return getInstance(view.getContext()).showTooltipNow(view, text, xoffset, yoffset); } public static Tooltip show(View view, CharSequence text, long delay) { return show(view, text, 0, 0, delay); } public static Tooltip show(View view, CharSequence text, int xoffset, int yoffset, long delay) { if (delay > 0) { return getInstance(view.getContext()).showTooltipLater(view, text, xoffset, yoffset, delay); } else { return show(view, text, xoffset, yoffset); } } public static Tooltip showAndHide(View view, CharSequence text, long duration) { return showAndHide(view, text, 0, 0, duration); } public static Tooltip showAndHide(View view, CharSequence text, int xoffset, int yoffset, long duration) { if (duration > 0) { Tooltip ret = getInstance(view.getContext()).showTooltipNow(view, text, xoffset, yoffset); instance.hideTooltipLater(duration); return ret; } return null; } public static void hide(View view) { getInstance(view.getContext()).hideTooltipNow(); } public static void hide(View view, long delay) { if (delay > 0) { getInstance(view.getContext()).hideTooltipLater(delay); } else { hide(view); } } private void resetContext(Context context) { // context changed hideTooltipNow(); handler.removeCallbacksAndMessages(null); this.context = context; } private Tooltip showTooltipNow(View view, CharSequence text, int xoffset, int yoffset) { final Tooltip tooltip = makeTooltip(text); doShow(tooltip, makeParams(view, xoffset, yoffset)); return tooltip; } private Tooltip showTooltipLater(View view, CharSequence text, int xoffset, int yoffset, long delay) { final Tooltip tooltip = makeTooltip(text); final WindowManager.LayoutParams params = makeParams(view, xoffset, yoffset); handler.postDelayed(new Runnable() { @Override public void run() { instance.doShow(tooltip, params); } }, delay); return tooltip; } private void hideTooltipNow() { doHide(tooltip); tooltip = null; } private void hideTooltipLater(long delay) { final Tooltip tt = tooltip; handler.postDelayed(new Runnable() { @Override public void run() { instance.doHide(tt); if (tt == tooltip) tooltip = null; } }, delay); } private static boolean isValid(Context context) { if (context != null && context instanceof Activity) { Activity act = (Activity) context; return !act.isFinishing(); } else { return false; } } private Tooltip makeTooltip(CharSequence text) { Tooltip tooltip = (Tooltip) LayoutInflater.from(context).inflate(R.layout.tooltip, null); tooltip.setText(text); return tooltip; } private static WindowManager.LayoutParams makeParams(View view, int xoffset, int yoffset) { final int[] screenPos = new int[2]; final Rect displayFrame = new Rect(); view.getLocationOnScreen(screenPos); view.getWindowVisibleDisplayFrame(displayFrame); WindowManager.LayoutParams params = Tooltip.getDefaultLayoutParams(); params.gravity = Gravity.TOP | Gravity.LEFT; params.x = xoffset + screenPos[0] - displayFrame.left; params.y = yoffset + screenPos[1] - displayFrame.top; return params; } private void doShow(Tooltip tooltip, WindowManager.LayoutParams params) { if (!isValid(context)) return; // skip if context if not valid WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); wm.addView(tooltip, params); // Show new tooltip first. doHide(this.tooltip); // Then hide existing tooltip if any. this.tooltip = tooltip; } private void doHide(Tooltip tooltip) { if (tooltip != null && tooltip.getParent() != null){ // Make sure it's attached before removing. WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); wm.removeView(tooltip); } } }