public abstract class BasicWindow {
public WindowManager.LayoutParams mLayoutParams;
public WindowManager mWindowManager;
public View mView;
public Context context;
public void init(Context context) {
this.context = context;
initWindow();
createView();
initData();
initListener();
}
protected void initWindow() {
if (mWindowManager == null) {
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
}
if (mLayoutParams == null) {
mLayoutParams = new WindowManager.LayoutParams();
mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
mLayoutParams.format = PixelFormat.RGBA_8888;
mLayoutParams.flags = WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
mLayoutParams.windowAnimations = R.style.sitech_window_anim;
mLayoutParams.x = 150;
mLayoutParams.width = 1770;
mLayoutParams.height = 720;
}
}
private void createView() {
if (mView == null) {
mView = LayoutInflater.from(context).inflate(getLayoutId(), null);
findView();
}
}
public void initData() {
}
public abstract int getLayoutId();
public abstract void findView();
public void initListener() {
}
public void showWnd() {
if (mWindowManager != null && mView != null && !mView.isShown()) {
mWindowManager.addView(mView, mLayoutParams);
}
}
public void hideWnd() {
if (mWindowManager != null && mView != null && mView.isShown()) {
mWindowManager.removeViewImmediate(mView);
}
}
public boolean isShow() {
return mWindowManager != null && mView != null && mView.isShown();
}
}
public class BaseToast extends BasicWindow {
private final String TAG = BaseToast.class.getSimpleName();
private TextView mToastTextView = null;
private Handler handler = null;
private long durationTime = 0L;
private BaseToast() {
handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0://展示Window
showWnd();
handler.postDelayed(() -> handler.sendEmptyMessage(1), durationTime);
break;
case 1://關閉Window
hideWnd();
break;
default:
break;
}
}
};
}
private static class SingleBaseToast {
private static BaseToast instance = new BaseToast();
}
public static BaseToast getInstance() {
return SingleBaseToast.instance;
}
@Override
public int getLayoutId() {
return R.layout.all_toast_view;
}
@Override
public void findView() {
mToastTextView = mView.findViewById(R.id.tv_toast_tip);
mLayoutParams.width = 350;
mLayoutParams.height = 114;
}
public void showToast(String text, int duration) {
hideWnd();
if (mToastTextView != null) {
mToastTextView.setText(text);
}
switch (duration) {
case Toast.LENGTH_LONG:
durationTime = 3500L;
break;
case Toast.LENGTH_SHORT:
durationTime = 2000L;
break;
default:
durationTime = 2000L;
break;
}
handler.post(() -> handler.sendEmptyMessage(0));
}
@Override
public void hideWnd() {
super.hideWnd();
handler.removeMessages(0);
handler.removeMessages(1);
}
}
public class ToastUtils {
private static final int COLOR_DEFAULT = 0xFEFFFFFF;
private static final Handler HANDLER = new Handler(Looper.getMainLooper());
private static Toast sToast;
private static int sGravity = -1;
private static int sXOffset = -1;
private static int sYOffset = -1;
private static int sBgColor = COLOR_DEFAULT;
private static int sBgResource = -1;
private static int sMsgColor = COLOR_DEFAULT;
private static int sMsgTextSize = -1;
private ToastUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
/**
* Set the gravity.
*
* @param gravity The gravity.
* @param xOffset X-axis offset, in pixel.
* @param yOffset Y-axis offset, in pixel.
*/
public static void setGravity(final int gravity, final int xOffset, final int yOffset) {
sGravity = gravity;
sXOffset = xOffset;
sYOffset = yOffset;
}
/**
* Set the color of background.
*
* @param backgroundColor The color of background.
*/
public static void setBgColor(@ColorInt final int backgroundColor) {
sBgColor = backgroundColor;
}
/**
* Set the resource of background.
*
* @param bgResource The resource of background.
*/
public static void setBgResource(@DrawableRes final int bgResource) {
sBgResource = bgResource;
}
/**
* Set the color of message.
*
* @param msgColor The color of message.
*/
public static void setMsgColor(@ColorInt final int msgColor) {
sMsgColor = msgColor;
}
/**
* Set the text size of message.
*
* @param textSize The text size of message.
*/
public static void setMsgTextSize(final int textSize) {
sMsgTextSize = textSize;
}
/**
* Show the sToast for a short period of time.
*
* @param text The text.
*/
public static void showShort(@NonNull final CharSequence text) {
show(text, Toast.LENGTH_SHORT);
}
/**
* Show the sToast for a short period of time.
*
* @param resId The resource id for text.
*/
public static void showShort(@StringRes final int resId) {
show(resId, Toast.LENGTH_SHORT);
}
/**
* Show the sToast for a short period of time.
*
* @param resId The resource id for text.
* @param args The args.
*/
public static void showShort(@StringRes final int resId, final Object... args) {
if (args != null && args.length == 0) {
show(resId, Toast.LENGTH_SHORT);
} else {
show(resId, Toast.LENGTH_SHORT, args);
}
}
/**
* Show the sToast for a short period of time.
*
* @param format The format.
* @param args The args.
*/
public static void showShort(final String format, final Object... args) {
if (args != null && args.length == 0) {
show(format, Toast.LENGTH_SHORT);
} else {
show(format, Toast.LENGTH_SHORT, args);
}
}
/**
* Show the sToast for a long period of time.
*
* @param text The text.
*/
public static void showLong(@NonNull final CharSequence text) {
show(text, Toast.LENGTH_LONG);
}
/**
* Show the sToast for a long period of time.
*
* @param resId The resource id for text.
*/
public static void showLong(@StringRes final int resId) {
show(resId, Toast.LENGTH_LONG);
}
/**
* Show the sToast for a long period of time.
*
* @param resId The resource id for text.
* @param args The args.
*/
public static void showLong(@StringRes final int resId, final Object... args) {
if (args != null && args.length == 0) {
show(resId, Toast.LENGTH_SHORT);
} else {
show(resId, Toast.LENGTH_LONG, args);
}
}
/**
* Show the sToast for a long period of time.
*
* @param format The format.
* @param args The args.
*/
public static void showLong(final String format, final Object... args) {
if (args != null && args.length == 0) {
show(format, Toast.LENGTH_SHORT);
} else {
show(format, Toast.LENGTH_LONG, args);
}
}
/**
* Show custom sToast for a short period of time.
*
* @param layoutId ID for an XML layout resource to load.
*/
public static View showCustomShort(@LayoutRes final int layoutId) {
final View view = getView(layoutId);
show(view, Toast.LENGTH_SHORT);
return view;
}
/**
* Show custom sToast for a long period of time.
*
* @param layoutId ID for an XML layout resource to load.
*/
public static View showCustomLong(@LayoutRes final int layoutId) {
final View view = getView(layoutId);
show(view, Toast.LENGTH_LONG);
return view;
}
/**
* Cancel the sToast.
*/
public static void cancel() {
if (sToast != null) {
sToast.cancel();
}
}
private static void show(@StringRes final int resId, final int duration) {
show(AppUtils.getApp().getResources().getText(resId).toString(), duration);
}
private static void show(@StringRes final int resId, final int duration, final Object... args) {
show(String.format(AppUtils.getApp().getResources().getString(resId), args), duration);
}
private static void show(final String format, final int duration, final Object... args) {
show(String.format(format, args), duration);
}
private static void show(final CharSequence text, final int duration) {
if (StringUtils.isEmpty(text)) {
return;
}
HANDLER.post(() -> {
cancel();
showToast((String) text, duration);
});
}
private static void show(final View view, final int duration) {
HANDLER.post(() -> {
cancel();
showToast("", duration);
});
}
private static void showToast(String text, int duration) {
BaseToast.getInstance().showToast(text, duration);
}
private static void showToast() {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N_MR1) {
try {
Field field = View.class.getDeclaredField("mContext");
field.setAccessible(true);
field.set(sToast.getView(), new ApplicationContextWrapperForApi25());
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
sToast.show();
}
private static void setBg() {
if (sBgResource != -1) {
final View toastView = sToast.getView();
toastView.setBackgroundResource(sBgResource);
} else if (sBgColor != COLOR_DEFAULT) {
final View toastView = sToast.getView();
Drawable background = toastView.getBackground();
if (background != null) {
background.setColorFilter(
new PorterDuffColorFilter(sBgColor, PorterDuff.Mode.SRC_IN)
);
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
toastView.setBackground(new ColorDrawable(sBgColor));
} else {
toastView.setBackgroundDrawable(new ColorDrawable(sBgColor));
}
}
}
}
private static void setBg(final TextView tvMsg) {
if (sBgResource != -1) {
final View toastView = sToast.getView();
toastView.setBackgroundResource(sBgResource);
tvMsg.setBackgroundColor(Color.TRANSPARENT);
} else if (sBgColor != COLOR_DEFAULT) {
final View toastView = sToast.getView();
Drawable tvBg = toastView.getBackground();
Drawable msgBg = tvMsg.getBackground();
if (tvBg != null && msgBg != null) {
tvBg.setColorFilter(new PorterDuffColorFilter(sBgColor, PorterDuff.Mode.SRC_IN));
tvMsg.setBackgroundColor(Color.TRANSPARENT);
} else if (tvBg != null) {
tvBg.setColorFilter(new PorterDuffColorFilter(sBgColor, PorterDuff.Mode.SRC_IN));
} else if (msgBg != null) {
msgBg.setColorFilter(new PorterDuffColorFilter(sBgColor, PorterDuff.Mode.SRC_IN));
} else {
toastView.setBackgroundColor(sBgColor);
}
}
}
private static View getView(@LayoutRes final int layoutId) {
LayoutInflater inflate =
(LayoutInflater) AppUtils.getApp().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return inflate != null ? inflate.inflate(layoutId, null) : null;
}
private static final class ApplicationContextWrapperForApi25 extends ContextWrapper {
ApplicationContextWrapperForApi25() {
super(AppUtils.getApp());
}
@Override
public Context getApplicationContext() {
return this;
}
@Override
public Object getSystemService(@NonNull String name) {
if (Context.WINDOW_SERVICE.equals(name)) {
// noinspection ConstantConditions
return new WindowManagerWrapper(
(WindowManager) getBaseContext().getSystemService(name)
);
}
return super.getSystemService(name);
}
private static final class WindowManagerWrapper implements WindowManager {
private final WindowManager base;
private WindowManagerWrapper(@NonNull WindowManager base) {
this.base = base;
}
@Override
public Display getDefaultDisplay() {
return base.getDefaultDisplay();
}
@Override
public void removeViewImmediate(View view) {
base.removeViewImmediate(view);
}
@Override
public void addView(View view, ViewGroup.LayoutParams params) {
try {
base.addView(view, params);
} catch (BadTokenException e) {
} catch (Throwable throwable) {
}
}
@Override
public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
base.updateViewLayout(view, params);
}
@Override
public void removeView(View view) {
base.removeView(view);
}
}
}
}