public final class ToastUtils {
private static final int? ? COLOR_DEFAULT =0xFEFFFFFF;
? ? private static final StringNULL? ? ? ? ? ="null";
? ? private static IToastiToast;
? ? 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 toast for a short period of time.
*
? ? * @param text The text.
*/
? ? public static void showShort(final CharSequence text) {
show(text ==null ?NULL : text, Toast.LENGTH_SHORT);
? ? }
/**
* Show the toast 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 toast 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) {
show(resId, Toast.LENGTH_SHORT, args);
? ? }
/**
* Show the toast for a short period of time.
*
? ? * @param format The format.
? ? * @param args? The args.
*/
? ? public static void showShort(final String format, final Object... args) {
show(format, Toast.LENGTH_SHORT, args);
? ? }
/**
* Show the toast for a long period of time.
*
? ? * @param text The text.
*/
? ? public static void showLong(final CharSequence text) {
show(text ==null ?NULL : text, Toast.LENGTH_LONG);
? ? }
/**
* Show the toast 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 toast 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) {
show(resId, Toast.LENGTH_LONG, args);
? ? }
/**
* Show the toast for a long period of time.
*
? ? * @param format The format.
? ? * @param args? The args.
*/
? ? public static void showLong(final String format, final Object... args) {
show(format, Toast.LENGTH_LONG, args);
? ? }
/**
* Show custom toast for a short period of time.
*
? ? * @param layoutId ID for an XML layout resource to load.
*/
? ? public static ViewshowCustomShort(@LayoutRes final int layoutId) {
return showCustomShort(getView(layoutId));
? ? }
/**
* Show custom toast for a short period of time.
*
? ? * @param view The view of toast.
*/
? ? public static ViewshowCustomShort(final View view) {
show(view, Toast.LENGTH_SHORT);
? ? ? ? return view;
? ? }
/**
* Show custom toast for a long period of time.
*
? ? * @param layoutId ID for an XML layout resource to load.
*/
? ? public static ViewshowCustomLong(@LayoutRes final int layoutId) {
return showCustomLong(getView(layoutId));
? ? }
/**
* Show custom toast for a long period of time.
*
? ? * @param view The view of toast.
*/
? ? public static ViewshowCustomLong(final View view) {
show(view, Toast.LENGTH_LONG);
? ? ? ? return view;
? ? }
/**
* Cancel the toast.
*/
? ? public static void cancel() {
if (iToast !=null) {
iToast.cancel();
? ? ? ? }
}
private static void show(final int resId, final int duration) {
show(resId, duration, (Object)null);
? ? }
private static void show(final int resId, final int duration, final Object... args) {
try {
CharSequence text = Utils.getApp().getResources().getText(resId);
? ? ? ? ? ? if (args !=null) {
text = String.format(text.toString(), args);
? ? ? ? ? ? }
show(text, duration);
? ? ? ? }catch (Exception ignore) {
show(String.valueOf(resId), duration);
? ? ? ? }
}
private static void show(final String format, final int duration, final Object... args) {
String text = format;
? ? ? ? if (text ==null) {
text =NULL;
? ? ? ? }else {
if (args !=null) {
text = String.format(format, args);
? ? ? ? ? ? }
}
show(text, duration);
? ? }
private static void show(final CharSequence text, final int duration) {
Utils.runOnUiThread(new Runnable() {
@SuppressLint("ShowToast")
@Override
? ? ? ? ? ? public void run() {
cancel();
? ? ? ? ? ? ? ? iToast = ToastFactory.makeToast(Utils.getApp(), text, duration);
? ? ? ? ? ? ? ? final View toastView =iToast.getView();
? ? ? ? ? ? ? ? if (toastView ==null)return;
? ? ? ? ? ? ? ? final TextView tvMessage = toastView.findViewById(android.R.id.message);
? ? ? ? ? ? ? ? if (sMsgColor !=COLOR_DEFAULT) {
tvMessage.setTextColor(sMsgColor);
? ? ? ? ? ? ? ? }
if (sMsgTextSize != -1) {
tvMessage.setTextSize(sMsgTextSize);
? ? ? ? ? ? ? ? }
if (sGravity != -1 ||sXOffset != -1 ||sYOffset != -1) {
iToast.setGravity(sGravity, sXOffset, sYOffset);
? ? ? ? ? ? ? ? }
setBg(tvMessage);
? ? ? ? ? ? ? ? iToast.show();
? ? ? ? ? ? }
});
? ? }
private static void show(final View view, final int duration) {
Utils.runOnUiThread(new Runnable() {
@Override
? ? ? ? ? ? public void run() {
cancel();
? ? ? ? ? ? ? ? iToast = ToastFactory.newToast(Utils.getApp());
? ? ? ? ? ? ? ? iToast.setView(view);
? ? ? ? ? ? ? ? iToast.setDuration(duration);
? ? ? ? ? ? ? ? if (sGravity != -1 ||sXOffset != -1 ||sYOffset != -1) {
iToast.setGravity(sGravity, sXOffset, sYOffset);
? ? ? ? ? ? ? ? }
setBg();
? ? ? ? ? ? ? ? iToast.show();
? ? ? ? ? ? }
});
? ? }
private static void setBg() {
if (sBgResource != -1) {
final View toastView =iToast.getView();
? ? ? ? ? ? toastView.setBackgroundResource(sBgResource);
? ? ? ? }else if (sBgColor !=COLOR_DEFAULT) {
final View toastView =iToast.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 =iToast.getView();
? ? ? ? ? ? toastView.setBackgroundResource(sBgResource);
? ? ? ? ? ? tvMsg.setBackgroundColor(Color.TRANSPARENT);
? ? ? ? }else if (sBgColor !=COLOR_DEFAULT) {
final View toastView =iToast.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 ViewgetView(@LayoutRes final int layoutId) {
LayoutInflater inflate =
(LayoutInflater) Utils.getApp().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
? ? ? ? return inflate.inflate(layoutId, null);
? ? }
static class ToastFactory {
static IToastmakeToast(Context context, CharSequence text, int duration) {
if (NotificationManagerCompat.from(context).areNotificationsEnabled()) {
return new SystemToast(makeNormalToast(context, text, duration));
? ? ? ? ? ? }
return new ToastWithoutNotification(makeNormalToast(context, text, duration));
? ? ? ? }
static IToastnewToast(Context context) {
if (NotificationManagerCompat.from(context).areNotificationsEnabled()) {
return new SystemToast(new Toast(context));
? ? ? ? ? ? }
return new ToastWithoutNotification(new Toast(context));
? ? ? ? }
private static ToastmakeNormalToast(Context context, CharSequence text, int duration) {
@SuppressLint("ShowToast")
Toast toast = Toast.makeText(context, "", duration);
? ? ? ? ? ? toast.setText(text);
? ? ? ? ? ? return toast;
? ? ? ? }
}
static class SystemToastextends AbsToast {
SystemToast(Toast toast) {
super(toast);
? ? ? ? ? ? if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N_MR1) {
try {
//noinspection JavaReflectionMemberAccess
? ? ? ? ? ? ? ? ? ? Field mTNField = Toast.class.getDeclaredField("mTN");
? ? ? ? ? ? ? ? ? ? mTNField.setAccessible(true);
? ? ? ? ? ? ? ? ? ? Object mTN = mTNField.get(toast);
? ? ? ? ? ? ? ? ? ? Field mTNmHandlerField = mTNField.getType().getDeclaredField("mHandler");
? ? ? ? ? ? ? ? ? ? mTNmHandlerField.setAccessible(true);
? ? ? ? ? ? ? ? ? ? Handler tnHandler = (Handler) mTNmHandlerField.get(mTN);
? ? ? ? ? ? ? ? ? ? mTNmHandlerField.set(mTN, new SafeHandler(tnHandler));
? ? ? ? ? ? ? ? }catch (Exception ignored) {/**/}
}
}
@Override
? ? ? ? public void show() {
mToast.show();
? ? ? ? }
@Override
? ? ? ? public void cancel() {
mToast.cancel();
? ? ? ? }
static class SafeHandlerextends Handler {
private Handlerimpl;
? ? ? ? ? ? SafeHandler(Handler impl) {
this.impl = impl;
? ? ? ? ? ? }
@Override
? ? ? ? ? ? public void handleMessage(Message msg) {
impl.handleMessage(msg);
? ? ? ? ? ? }
@Override
? ? ? ? ? ? public void dispatchMessage(Message msg) {
try {
impl.dispatchMessage(msg);
? ? ? ? ? ? ? ? }catch (Exception e) {
Log.e("ToastUtils", e.toString());
? ? ? ? ? ? ? ? }
}
}
}
static class ToastWithoutNotificationextends AbsToast {
private ViewmView;
? ? ? ? private WindowManagermWM;
? ? ? ? private WindowManager.LayoutParamsmParams =new WindowManager.LayoutParams();
? ? ? ? private static final Utils.OnActivityDestroyedListenerLISTENER =
new Utils.OnActivityDestroyedListener() {
@Override
? ? ? ? ? ? ? ? ? ? public void onActivityDestroyed(Activity activity) {
if (iToast ==null)return;
? ? ? ? ? ? ? ? ? ? ? ? activity.getWindow().getDecorView().setVisibility(View.GONE);
? ? ? ? ? ? ? ? ? ? ? ? iToast.cancel();
? ? ? ? ? ? ? ? ? ? }
};
? ? ? ? ToastWithoutNotification(Toast toast) {
super(toast);
? ? ? ? }
@Override
? ? ? ? public void show() {
Utils.runOnUiThreadDelayed(new Runnable() {
@Override
? ? ? ? ? ? ? ? public void run() {
realShow();
? ? ? ? ? ? ? ? }
}, 300);
? ? ? ? }
private void realShow() {
if (mToast ==null)return;
? ? ? ? ? ? mView =mToast.getView();
? ? ? ? ? ? if (mView ==null)return;
? ? ? ? ? ? final Context context =mToast.getView().getContext();
? ? ? ? ? ? if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
mWM = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
? ? ? ? ? ? ? ? mParams.type = WindowManager.LayoutParams.TYPE_TOAST;
? ? ? ? ? ? }else {
Context topActivityOrApp = Utils.getTopActivityOrApp();
? ? ? ? ? ? ? ? if (!(topActivityOrAppinstanceof Activity)) {
Log.e("ToastUtils", "Couldn't get top Activity.");
return;
? ? ? ? ? ? ? ? }
Activity topActivity = (Activity) topActivityOrApp;
? ? ? ? ? ? ? ? if (topActivity.isFinishing() || topActivity.isDestroyed()) {
Log.e("ToastUtils", topActivity +" is useless");
return;
? ? ? ? ? ? ? ? }
mWM = topActivity.getWindowManager();
? ? ? ? ? ? ? ? mParams.type = WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
? ? ? ? ? ? ? ? Utils.getActivityLifecycle().addOnActivityDestroyedListener(topActivity, LISTENER);
? ? ? ? ? ? }
mParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
? ? ? ? ? ? mParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
? ? ? ? ? ? mParams.format = PixelFormat.TRANSLUCENT;
? ? ? ? ? ? mParams.windowAnimations = android.R.style.Animation_Toast;
? ? ? ? ? ? mParams.setTitle("ToastWithoutNotification");
? ? ? ? ? ? mParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
? ? ? ? ? ? ? ? ? ? | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
? ? ? ? ? ? ? ? ? ? | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
? ? ? ? ? ? mParams.packageName = Utils.getApp().getPackageName();
? ? ? ? ? ? mParams.gravity =mToast.getGravity();
? ? ? ? ? ? if ((mParams.gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) {
mParams.horizontalWeight =1.0f;
? ? ? ? ? ? }
if ((mParams.gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) {
mParams.verticalWeight =1.0f;
? ? ? ? ? ? }
mParams.x =mToast.getXOffset();
? ? ? ? ? ? mParams.y =mToast.getYOffset();
? ? ? ? ? ? mParams.horizontalMargin =mToast.getHorizontalMargin();
? ? ? ? ? ? mParams.verticalMargin =mToast.getVerticalMargin();
? ? ? ? ? ? try {
if (mWM !=null) {
mWM.addView(mView, mParams);
? ? ? ? ? ? ? ? }
}catch (Exception ignored) {/**/}
Utils.runOnUiThreadDelayed(new Runnable() {
@Override
? ? ? ? ? ? ? ? public void run() {
cancel();
? ? ? ? ? ? ? ? }
}, mToast.getDuration() == Toast.LENGTH_SHORT ?2000 :3500);
? ? ? ? }
@Override
? ? ? ? public void cancel() {
try {
if (mWM !=null) {
mWM.removeViewImmediate(mView);
? ? ? ? ? ? ? ? }
}catch (Exception ignored) {/**/}
mView =null;
? ? ? ? ? ? mWM =null;
? ? ? ? ? ? mToast =null;
? ? ? ? }
}
static abstract class AbsToastimplements IToast {
ToastmToast;
? ? ? ? AbsToast(Toast toast) {
mToast = toast;
? ? ? ? }
@Override
? ? ? ? public void setView(View view) {
mToast.setView(view);
? ? ? ? }
@Override
? ? ? ? public ViewgetView() {
return mToast.getView();
? ? ? ? }
@Override
? ? ? ? public void setDuration(int duration) {
mToast.setDuration(duration);
? ? ? ? }
@Override
? ? ? ? public void setGravity(int gravity, int xOffset, int yOffset) {
mToast.setGravity(gravity, xOffset, yOffset);
? ? ? ? }
@Override
? ? ? ? public void setText(int resId) {
mToast.setText(resId);
? ? ? ? }
@Override
? ? ? ? public void setText(CharSequence s) {
mToast.setText(s);
? ? ? ? }
}
interface IToast {
void show();
? ? ? ? void cancel();
? ? ? ? void setView(View view);
? ? ? ? ViewgetView();
? ? ? ? void setDuration(int duration);
? ? ? ? void setGravity(int gravity, int xOffset, int yOffset);
? ? ? ? void setText(@StringRes int resId);
? ? ? ? void setText(CharSequence s);
? ? }
}