前言
小米手机新系统,应用 Toast自带应用名,如:“应用名:Toast信息”(Toast会显示app的名称+显示的内容)
方法一:
需要先给Toast的message设置为空,然后再设置需要提示的message
public static void showShort(Context context, CharSequence message) {
Toast mToast = Toast.makeText(context, “”, Toast.LENGTH_LONG);
mToast.setText(message);
mToast.show();
}
方法二:
使用 Toast工具类
ToastUtils.showShort(R.string.xxxxxx);
/**
* Tooast相关工具类
*/
public class ToastUtils {
private static final int COLOR_DEFAULT = 0xFEFFFFFF;
private static final String NULL = "null";
private static IToast iToast;
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;
final static Map<Activity, Set<OnActivityDestroyedListener>> mDestroyedListenerMap = new HashMap<>();
public interface OnActivityDestroyedListener {
void onActivityDestroyed(Activity activity);
}
static void addOnActivityDestroyedListener(final Activity activity,
final OnActivityDestroyedListener listener) {
if (activity == null || listener == null) return;
Set<OnActivityDestroyedListener> listeners;
if (!mDestroyedListenerMap.containsKey(activity)) {
listeners = new HashSet<>();
mDestroyedListenerMap.put(activity, listeners);
} else {
listeners = mDestroyedListenerMap.get(activity);
if (listeners.contains(listener)) return;
}
listeners.add(listener);
}
public static void runOnUiThread(final Runnable runnable) {
if (Looper.myLooper() == Looper.getMainLooper()) {
runnable.run();
} else {
new Handler(Looper.getMainLooper()).post(runnable);
}
}
public static void runOnUiThreadDelayed(final Runnable runnable, long delayMillis) {
new Handler(Looper.getMainLooper()).postDelayed(runnable, delayMillis);
}
private ToastUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
/**
* 设定重力。
*
* @param gravity 重力。
* @param xOffset X轴偏移,以像素为单位。
* @param yOffset Y轴偏移,以像素为单位。
*/
public static void setGravity(final int gravity, final int xOffset, final int yOffset) {
sGravity = gravity;
sXOffset = xOffset;
sYOffset = yOffset;
}
/**
* 设置背景颜色。
*
* @param backgroundColor 背景的颜色。
*/
public static void setBgColor(@ColorInt final int backgroundColor) {
sBgColor = backgroundColor;
}
/**
* 设置背景资源。
*
* @param bgResource 背景资源。
*/
public static void setBgResource(@DrawableRes final int bgResource) {
sBgResource = bgResource;
}
/**
* 设置消息的颜色。
*
* @param msgColor 消息的颜色。
*/
public static void setMsgColor(@ColorInt final int msgColor) {
sMsgColor = msgColor;
}
/**
* 设置消息的文本大小。
*
* @param textSize 消息的文本大小。
*/
public static void setMsgTextSize(final int textSize) {
sMsgTextSize = textSize;
}
/**
* 在短时间内弹出。
*
* @param text 文本。
*/
public static void showShort(final CharSequence text) {
show(text == null ? NULL : text, Toast.LENGTH_SHORT);
}
/**
* 在短时间内弹出。
*
* @param resId 文本的资源ID。
*/
public static void showShort(@StringRes final int resId) {
show(resId, Toast.LENGTH_SHORT);
}
/**
* 在短时间内弹出。
*
* @param resId 文本的资源ID。
* @param args args。
*/
public static void showShort(@StringRes final int resId, final Object... args) {
show(resId, Toast.LENGTH_SHORT, args);
}
/**
* 在短时间内弹出。
*
* @param args args。
* @param format 格式。
*/
public static void showShort(final String format, final Object... args) {
show(format, Toast.LENGTH_SHORT, args);
}
/**
* 长时间展示吐司.
*
* @param text 文本.
*/
public static void showLong(final CharSequence text) {
show(text == null ? NULL : text, Toast.LENGTH_LONG);
}
/**
* 长时间展示吐司。
*
* @param resId 文本的资源ID。
*/
public static void showLong(@StringRes final int resId) {
show(resId, Toast.LENGTH_LONG);
}
/**
* 长时间展示吐司。
*
* @param resId 文本的资源ID。
* @param args args。
*/
public static void showLong(@StringRes final int resId, final Object... args) {
show(resId, Toast.LENGTH_LONG, args);
}
/**
* 长时间展示吐司。
*
* @param args args。
* @param format 格式。
*/
public static void showLong(final String format, final Object... args) {
show(format, Toast.LENGTH_LONG, args);
}
/**
* 在短时间内显示自定义吐司。
*
* @param layoutId 要加载的XML布局资源的ID。
*/
public static View showCustomShort(@LayoutRes final int layoutId) {
return showCustomShort(getView(layoutId));
}
/**
* 在短时间内显示自定义吐司。
*
* @param view 吐司的视图。
*/
public static View showCustomShort(final View view) {
show(view, Toast.LENGTH_SHORT);
return view;
}
/**
* 长时间显示定制吐司。
*
* @param layoutId 要加载的XML布局资源的ID。
*/
public static View showCustomLong(@LayoutRes final int layoutId) {
return showCustomLong(getView(layoutId));
}
/**
* 长时间显示定制吐司。
*
* @param view 吐司的视图。
*/
public static View showCustomLong(final View view) {
show(view, Toast.LENGTH_LONG);
return view;
}
/**
* 取消吐司。
*/
public static void cancel() {
if (iToast != null) {
iToast.cancel();
}
}
private static void show(final int resId, final int duration) {
try {
CharSequence text = MyApplication.getmContext().getText(resId);
show(text, duration);
} catch (Exception ignore) {
show(String.valueOf(resId), duration);
}
}
private static void show(final int resId, final int duration, final Object... args) {
try {
CharSequence text = MyApplication.getmContext().getText(resId);
String format = String.format(text.toString(), args);
show(format, duration);
} catch (Exception ignore) {
show(String.valueOf(resId), duration);
}
}
private static void show(final String format, final int duration, final Object... args) {
String text;
if (format == null) {
text = NULL;
} else {
text = String.format(format, args);
if (text == null) {
text = NULL;
}
}
show(text, duration);
}
private static void show(final CharSequence text, final int duration) {
runOnUiThread(new Runnable() {
@SuppressLint("ShowToast")
@Override
public void run() {
cancel();
iToast = ToastFactory.makeToast(MyApplication.getmContext(), 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) {
runOnUiThread(new Runnable() {
@Override
public void run() {
cancel();
iToast = ToastFactory.newToast(MyApplication.getmContext());
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 View getView(@LayoutRes final int layoutId) {
LayoutInflater inflate =
(LayoutInflater) MyApplication.getmContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//noinspection ConstantConditions
return inflate.inflate(layoutId, null);
}
static class ToastFactory {
static IToast makeToast(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 IToast newToast(Context context) {
// if (NotificationManagerCompat.from(context).areNotificationsEnabled()) {
// return new SystemToast(new Toast(context));
// }
return new ToastWithoutNotification(new Toast(context));
}
private static Toast makeNormalToast(Context context, CharSequence text, int duration) {
@SuppressLint("ShowToast")
Toast toast = Toast.makeText(context, "", duration);
toast.setText(text);
return toast;
}
}
static class SystemToast extends 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 SafeHandler extends Handler {
private Handler impl;
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 ToastWithoutNotification extends AbsToast {
private View mView;
private WindowManager mWM;
private WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
private static final OnActivityDestroyedListener LISTENER =
new 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() {
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 = MyApplication.getCurrentActivity();
if (!(topActivityOrApp instanceof 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;
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 = MyApplication.getmContext().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) { /**/ }
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 AbsToast implements IToast {
Toast mToast;
AbsToast(Toast toast) {
mToast = toast;
}
@Override
public void setView(View view) {
mToast.setView(view);
}
@Override
public View getView() {
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);
View getView();
void setDuration(int duration);
void setGravity(int gravity, int xOffset, int yOffset);
void setText(@StringRes int resId);
void setText(CharSequence s);
}
}