Android ToastUtil
自定义的一套ToastUtil,包括SuperToast、ToastStyle、ToastHandler、ToastUtil四个类。
/**
* toast显示,用来代替系统toast和snackbar。相对于系统控件更加灵活,比如可以设置任意时间等。<br/>
* <p>
* 如果要系统层级显示toast设置参数{@link ToastStyle#LEVEL_SYSTEM},如果是在App页面内显示即页面退出toast也消失,设置参数{@link
* ToastStyle#LEVEL_ACTIVITY}。<br/>
* <p>
* {@link #create()}必须调用,且在设置参数之后{@link #show()}方法之前。<br/>
* <p>
* 显示时间默认3000毫秒。
*
* @author 己师
*/
public class SuperToast {
private Context mContext;
private OnDismissListener mDismissListener;
private ToastStyle mToastStyle;
private View mView;
private TextView mTvMessage;
private ViewGroup mViewGroup;
public SuperToast(Context context) {
mContext = context;
mToastStyle = new ToastStyle();
}
public OnDismissListener getDismissListener() {
return mDismissListener;
}
@PriorityLevel
public int getPriorityLevel() {
return mToastStyle.priorityLevel;
}
public Animator getShowAnimator() {
return mToastStyle.showAnimator;
}
public Animator getHideAnimator() {
return mToastStyle.hideAnimator;
}
public Context getContext() {
return mContext;
}
public int getDisplayLevel() {
return mToastStyle.displayLevel;
}
public int getDuration() {
return mToastStyle.duration;
}
public long getTimestamp() {
return mToastStyle.timestamp;
}
public View getView() {
return mView;
}
public ViewGroup getViewGroup() {
if (mViewGroup == null) {
if (!(mContext instanceof Activity)) {
throw new IllegalArgumentException("使用LEVEL_ACTIVITY层级的toast Context需要是Activity");
}
mViewGroup = ((Activity) mContext).findViewById(android.R.id.content);
}
return mViewGroup;
}
public LayoutParams getWindowParams() {
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
layoutParams.height = mToastStyle.height;
layoutParams.width = mToastStyle.width;
if (mToastStyle.canTouch) {
layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR |
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
} else {
layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
}
layoutParams.format = PixelFormat.TRANSLUCENT;
layoutParams.type = WindowManager.LayoutParams.TYPE_TOAST;
layoutParams.windowAnimations = mToastStyle.animationId;
layoutParams.gravity = mToastStyle.gravity;
layoutParams.x = mToastStyle.xOffset;
layoutParams.y = mToastStyle.yOffset;
return layoutParams;
}
/**
* 自定义显示样式
*/
public SuperToast setToastStyle(ToastStyle toastStyle) {
mToastStyle = toastStyle;
return this;
}
/**
* 自定义显示的View
*
* @param viewId 自定义view的layout
*/
public SuperToast setView(@LayoutRes int viewId) {
mToastStyle.layoutId = viewId;
return this;
}
/**
* 自定义显示的View
*
* @param view 自定义view
*/
public SuperToast setView(View view) {
mView = view;
return this;
}
/**
* LEVEL_ACTIVITY显示层级,设置toast依附的ViewGroup,默认是根ViewGroup
*/
public SuperToast setViewGroup(ViewGroup viewGroup) {
mViewGroup = viewGroup;
return this;
}
/**
* 设置显示的文本
*/
public SuperToast setMessage(String message) {
mToastStyle.message = message;
return this;
}
/**
* 设置显示的文本
*
* @param message 资源id
*/
public SuperToast setMessage(@StringRes int message) {
mToastStyle.message = mContext.getString(message);
return this;
}
/**
* 设置显示文本的颜色
*
* @param color 色值
*/
public SuperToast setTextColor(@ColorInt int color) {
mToastStyle.messageTextColor = color;
return this;
}
/**
* 设置显示文本的大小
*
* @param textSize px值
*/
public SuperToast setTextSize(int textSize) {
mToastStyle.messageTextSize = textSize;
return this;
}
/**
* 设置文本旁边的icon
*
* @param iconRes icon资源id
*/
public SuperToast setIconRes(@DrawableRes int iconRes) {
mToastStyle.messageIconRes = iconRes;
return this;
}
/**
* 设置icon在文字显示的位置
*
* @param position 上下左右
*/
public SuperToast setIconPosition(@IconPosition int position) {
mToastStyle.messageIconPosition = position;
return this;
}
/**
* 设置背景色
*
* @param background 色值
*/
public SuperToast setBackground(@ColorInt int background) {
mToastStyle.backgroundColor = background;
return this;
}
/**
* 设置背景图片
*
* @param background 图片
*/
public SuperToast setBackground(Drawable background) {
mToastStyle.background = background;
return this;
}
/**
* 设置toast的圆角度数
*/
public SuperToast setRadius(int radius) {
mToastStyle.radius = radius;
return this;
}
/**
* 系统层级显示toast设置参数{@link ToastStyle#LEVEL_SYSTEM};<br/>
* App页面内显示即页面退出toast也消失,设置参数{@link ToastStyle#LEVEL_ACTIVITY}。
*
* @param displayLevel 显示层级
*/
public SuperToast setDisplayLevel(@DisplayLevel int displayLevel) {
mToastStyle.displayLevel = displayLevel;
return this;
}
/**
* 设置toast是否可操作。默认不可操作。在LEVEL_ACTIVITY层级一直可以操作。
*
* @param canTouch true 可以操作
*/
public SuperToast setCanTouch(boolean canTouch) {
mToastStyle.canTouch = canTouch;
return this;
}
/**
* 设置toast显示时间,小于0表示一直显示。默认三秒
*
* @param duration 毫秒值
*/
public SuperToast setDuration(int duration) {
mToastStyle.duration = duration;
return this;
}
/**
* 设置toast显示的优先级,
*
* @param priorityLevel 高({@link ToastStyle#PRIORITY_HIGH}),中({@link ToastStyle#PRIORITY_MEDIUM}),低({@link
* ToastStyle#PRIORITY_LOW})
*/
public SuperToast setPriorityLevel(@PriorityLevel int priorityLevel) {
mToastStyle.priorityLevel = priorityLevel;
return this;
}
/**
* 设置toast显示动画,该动画只在{@link ToastStyle#LEVEL_ACTIVITY}层级有效果
*/
public SuperToast setShowAnimator(Animator showAnimator) {
mToastStyle.showAnimator = showAnimator;
return this;
}
/**
* 设置toast显示动画,该动画只在{@link ToastStyle#LEVEL_ACTIVITY}层级有效果
*
* @param showAnimator 动画id
*/
public SuperToast setShowAnimator(@AnimatorRes int showAnimator) {
mToastStyle.showAnimator = AnimatorInflater.loadAnimator(mContext, showAnimator);
return this;
}
/**
* 设置toast隐藏动画,该动画只在{@link ToastStyle#LEVEL_ACTIVITY}层级有效果
*/
public SuperToast setHideAnimator(Animator hideAnimator) {
mToastStyle.hideAnimator = hideAnimator;
return this;
}
/**
* 设置toast隐藏动画,该动画只在{@link ToastStyle#LEVEL_ACTIVITY}层级有效果
*
* @param hideAnimator 动画id
*/
public SuperToast setHideAnimator(@AnimatorRes int hideAnimator) {
mToastStyle.hideAnimator = AnimatorInflater.loadAnimator(mContext, hideAnimator);
return this;
}
/**
* 用于{@link ToastStyle#LEVEL_SYSTEM}层级的toast的显示隐藏动画,且只能用系统动画资源,默认效果{@link android.R.style#Animation_Toast}
*
* @param animId 系统动画id
*/
public SuperToast setAnimations(int animId) {
mToastStyle.animationId = animId;
return this;
}
/**
* 设置toast的显示位置
*/
public SuperToast setGravity(@GravityStyle int gravity) {
mToastStyle.gravity = gravity;
return this;
}
/**
* 设置水平方向偏移量,左右的margin值
*
* @param xOffset 偏移量值px
*/
public SuperToast setXOffset(int xOffset) {
mToastStyle.xOffset = xOffset;
return this;
}
/**
* 设置竖直方向偏移量,上下的margin值
*
* @param yOffset 偏移量值px
*/
public SuperToast setYOffset(int yOffset) {
mToastStyle.yOffset = yOffset;
return this;
}
/**
* 设置宽 px,如果要用Match和Wrap 请使用{@link android.view.ViewGroup.LayoutParams#MATCH_PARENT } 或 {@link
* ViewGroup.LayoutParams#WRAP_CONTENT}
*/
public SuperToast setWidth(int width) {
mToastStyle.width = width;
return this;
}
/**
* 设置高 px;如果要用Match和Wrap 请使用{@link ViewGroup.LayoutParams#MATCH_PARENT } 或 {@link
* ViewGroup.LayoutParams#WRAP_CONTENT}
*/
public SuperToast setHeight(int height) {
mToastStyle.height = height;
return this;
}
/**
* 是否是一直显示
*/
public boolean isIndeterminate() {
return mToastStyle.duration < 0;
}
/**
* 判断是不是横竖屏转换,如果是,就不执行toast动画,否则就执行。
*/
protected boolean isFromOrientationChange() {
return false;
}
/**
* 判断当前toast是否正在显示中
*/
public boolean isShowing() {
return mView != null && mView.isShown();
}
/**
* 创建toast显示的View,默认是系统toast的布局
*/
protected View onCreateView() {
if (mView != null) {
return mView;
}
View view;
if (mToastStyle.displayLevel == ToastStyle.LEVEL_ACTIVITY) {
if (!(mContext instanceof Activity)) {
throw new IllegalArgumentException("使用LEVEL_ACTIVITY层级的toast Context需要是Activity");
}
mViewGroup = ((Activity) mContext).findViewById(android.R.id.content);
view = LayoutInflater.from(mContext)
.inflate(mToastStyle.layoutId, mViewGroup, false);
} else {
view = LayoutInflater.from(mContext)
.inflate(mToastStyle.layoutId, null);
}
//如果用的自定义的布局就不存在。
try {
mTvMessage = view.findViewById(R.id.tv_toast_message);
} catch (NotFoundException e) {
mTvMessage = null;
}
return view;
}
public SuperToast show() {
ToastHandler.getInstance().add(this);
sendAccessibilityEvent();
return this;
}
/**
* 创建布局,一定要在参数设置之后,show之前调用。
*/
public SuperToast create() {
mView = onCreateView();
if (mView.getBackground() == null) {
mView.setBackground(getBackground());
}
//api21以上加阴影效果。
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
mView.setElevation(3F);
}
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(mToastStyle.width, mToastStyle.height);
layoutParams.width = mToastStyle.width;
layoutParams.height = mToastStyle.height;
layoutParams.bottomMargin = mToastStyle.yOffset;
layoutParams.topMargin = mToastStyle.yOffset;
layoutParams.leftMargin = mToastStyle.xOffset;
layoutParams.rightMargin = mToastStyle.xOffset;
layoutParams.gravity = mToastStyle.gravity;
mView.setLayoutParams(layoutParams);
mView.setMinimumWidth(ResUtil.getDimen(R.dimen.x342));
mToastStyle.timestamp = System.currentTimeMillis();
//不等于空说明用的是默认布局。
if (mTvMessage != null) {
mTvMessage.setText(mToastStyle.message);
mTvMessage.setTextColor(mToastStyle.messageTextColor);
mTvMessage.setTextSize(TypedValue.COMPLEX_UNIT_PX, mToastStyle.messageTextSize);
if (mToastStyle.messageIconRes > 0) {
switch (mToastStyle.messageIconPosition) {
case ToastStyle.ICON_POSITION_LEFT:
mTvMessage.setCompoundDrawablesWithIntrinsicBounds(mToastStyle.messageIconRes, 0, 0, 0);
break;
case ToastStyle.ICON_POSITION_TOP:
mTvMessage.setCompoundDrawablesWithIntrinsicBounds(0, mToastStyle.messageIconRes, 0, 0);
break;
case ToastStyle.ICON_POSITION_RIGHT:
mTvMessage.setCompoundDrawablesWithIntrinsicBounds(0, 0, mToastStyle.messageIconRes, 0);
break;
case ToastStyle.ICON_POSITION_BOTTOM:
mTvMessage.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, mToastStyle.messageIconRes);
break;
default:
}
}
}
//好像不起作用
if (!mToastStyle.canTouch) {
mView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
}
return this;
}
/**
* 取消正在显示的toast并清空消息队列。
*/
public void cancelAllToasts() {
ToastHandler.getInstance().cancelAllToasts();
}
/**
* toast的背景
*/
private Drawable getBackground() {
if (mToastStyle.background == null) {
GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setColor(mToastStyle.backgroundColor);
gradientDrawable.setCornerRadius(mToastStyle.radius);
return gradientDrawable;
} else {
return mToastStyle.background;
}
}
/**
* 发送辅助功能事件。主要是了为了辅助残疾人士更好使用设备。
*/
private void sendAccessibilityEvent() {
AccessibilityManager am = (AccessibilityManager) mContext.getApplicationContext()
.getSystemService(Context.ACCESSIBILITY_SERVICE);
if (am == null || !am.isEnabled()) {
return;
}
final AccessibilityEvent accessibilityEvent = AccessibilityEvent
.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
accessibilityEvent.setClassName(mView.getClass().getName());
accessibilityEvent.setPackageName(mContext.getPackageName());
mView.dispatchPopulateAccessibilityEvent(accessibilityEvent);
am.sendAccessibilityEvent(accessibilityEvent);
}
/**
* 手动让toast的消失。
*/
public void dismiss() {
ToastHandler.getInstance().removeToast(this);
}
public SuperToast setOnDismissListener(OnDismissListener dismissListener) {
mDismissListener = dismissListener;
return this;
}
/**
* toast消失时的回调
*/
public interface OnDismissListener {
/**
* toast消失时会回调该方法。
*/
void onDismiss(View view);
}
}
/**
* toast的样式
* @author 己师
*/
class ToastStyle {
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, value = {PRIORITY_HIGH, PRIORITY_MEDIUM, PRIORITY_LOW})
public @interface PriorityLevel {}
public static final int PRIORITY_HIGH = 1;
public static final int PRIORITY_MEDIUM = 2;
public static final int PRIORITY_LOW = 3;
@SuppressLint("RtlHardcoded")
@Retention(RetentionPolicy.SOURCE)
@IntDef({Gravity.BOTTOM, Gravity.CENTER, Gravity.CENTER_HORIZONTAL,
Gravity.CENTER_VERTICAL, Gravity.END, Gravity.LEFT, Gravity.NO_GRAVITY,
Gravity.RIGHT, Gravity.START, Gravity.TOP})
public @interface GravityStyle {}
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, value = {LEVEL_SYSTEM, LEVEL_ACTIVITY})
public @interface DisplayLevel{}
public static final int LEVEL_SYSTEM = 10;
public static final int LEVEL_ACTIVITY = 20;
@Retention(RetentionPolicy.SOURCE)
@IntDef({ICON_POSITION_LEFT, ICON_POSITION_RIGHT, ICON_POSITION_BOTTOM, ICON_POSITION_TOP})
public @interface IconPosition {
}
public static final int ICON_POSITION_LEFT = 1;
public static final int ICON_POSITION_RIGHT = 2;
public static final int ICON_POSITION_BOTTOM = 3;
public static final int ICON_POSITION_TOP = 4;
public static final int DURATION_SHORT = 1000;
public static final int DURATION_LONG = 3000;
public static final int DURATION_INDEFINITE = -1;
/**
* 自定义view布局id
*/
@LayoutRes
public int layoutId;
public int style;
/**
* toast的显示层级,{@link #LEVEL_ACTIVITY} Activity层级,只显示在当前页面。{@link #LEVEL_SYSTEM} 系统层级,显示在所有页面最上层
*/
public int displayLevel;
/**
* toast显示时间
*/
public int duration;
/**
* toast的高度
*/
public int height;
/**
* toast的宽度
*/
public int width;
/**
* toast的显示层级是{@link #LEVEL_SYSTEM} 只能用系统的动画资源,如{@link android.R.style#Animation_Toast}
*/
public int animationId;
/**
* toast显示动画
*/
public Animator showAnimator;
/**
* toast隐藏动画
*/
public Animator hideAnimator;
/**
* toast显示位置
*/
public int gravity;
/**
* 水平方向偏移量,左右的margin值
*/
public int xOffset;
/**
* 竖直方法偏移量,上下的margin值
*/
public int yOffset;
/**
* toast的时间戳
*/
public long timestamp;
/**
* toast显示的文字
*/
public String message;
/**
* toast文字颜色,色值
*/
public int messageTextColor;
/**
* toast文字大小,px
*/
public float messageTextSize;
/**
* toast文字旁边的icon资源id
*/
public int messageIconRes;
/**
* icon在toast文字的位置,上下左右
*/
public int messageIconPosition;
/**
* toast背景色, 色值
*/
public int backgroundColor;
/**
* toast背景图, 图片
*/
public Drawable background;
/**
* toast的圆角度数
*/
public float radius;
/**
* toast的优先级,高中低,默认是中
*/
public int priorityLevel;
/**
* 设置toast是否可以操作。
*/
public boolean canTouch;
public ToastStyle() {
layoutId = R.layout.layout_normal_toast;
width = LayoutParams.WRAP_CONTENT;
height = ResUtil.getDimen(R.dimen.y90);
animationId = android.R.style.Animation_Toast;
duration = DURATION_LONG;
gravity = Gravity.CENTER;
yOffset = -ResUtil.getDimen(R.dimen.y136);
radius = ResUtil.getDimen(R.dimen.m4);
backgroundColor = ResUtil.getColor(R.color.information_main_color);
priorityLevel = PRIORITY_MEDIUM;
messageTextColor = ResUtil.getColor(R.color.text_color_1);
messageTextSize = ResUtil.getDimen(R.dimen.text_size1);
messageIconPosition = ICON_POSITION_LEFT;
ObjectAnimator objectAnimator1 = new ObjectAnimator();
objectAnimator1.setPropertyName("alpha");
objectAnimator1.setDuration(250).setFloatValues(0F,1F);
showAnimator = objectAnimator1;
ObjectAnimator objectAnimator2 = new ObjectAnimator();
objectAnimator2.setPropertyName("alpha");
objectAnimator2.setDuration(250).setFloatValues(1F,0F);
hideAnimator = objectAnimator2;
canTouch = false;
displayLevel = LEVEL_SYSTEM;
}
}
/**
* toast消息队列
* @author 己师
*/
class ToastHandler extends Handler {
private static ToastHandler mToastHandler;
private final PriorityQueue<SuperToast> mToastPriorityQueue;
private ToastHandler() {
mToastPriorityQueue = new PriorityQueue<>(10, new ToastComparator());
}
static ToastHandler getInstance() {
if (mToastHandler == null) {
synchronized (ToastHandler.class) {
if (mToastHandler == null) {
mToastHandler = new ToastHandler();
}
}
}
return mToastHandler;
}
/**
* 添加一个toast对象到信息队列
*/
void add(SuperToast superToast) {
mToastPriorityQueue.add(superToast);
showNextToast();
}
/**
* 在当前队列显示下一条toast,如果有toast正在显示就不执行任何操作。当当前正在显示的toast消失后会调用该方法
*/
private void showNextToast() {
if (mToastPriorityQueue.isEmpty()) {
return;
}
//从队列最顶部取toast
final SuperToast superToast = mToastPriorityQueue.peek();
if (!superToast.isShowing()) {
final Message message = obtainMessage(Messages.DISPLAY_TOAST);
message.obj = superToast;
sendMessage(message);
}
}
@Override
public void handleMessage(Message msg) {
final SuperToast superToast = (SuperToast) msg.obj;
switch (msg.what) {
case Messages.SHOW_NEXT:
showNextToast();
break;
case Messages.DISPLAY_TOAST:
displayToast(superToast);
break;
case Messages.REMOVE_TOAST:
removeToast(superToast);
break;
default:
super.handleMessage(msg);
break;
}
}
/**
* 该方法是显示toast的具体方法。
* <p></p>
* 既可以使用WindowManager来显示,这样会显示在全局和系统toast一样;
* 也可以使用外部提供的ViewGroup,这样只会显示在当前页面,和系统的snackbar一样,页面关闭toast也消失。
*/
private void displayToast(SuperToast superToast) {
if (superToast.isShowing()) {
return;
}
long animDuration = 0;
//如果toast显示层级是系统级别就使用WindowManager,层级和系统toast一样。
if (superToast.getDisplayLevel() == ToastStyle.LEVEL_SYSTEM) {
WindowManager wm = (WindowManager) superToast.getContext().getApplicationContext()
.getSystemService(Context.WINDOW_SERVICE);
if (wm != null) {
View view = superToast.getView();
view.setMinimumWidth(ResUtil.getDimen(R.dimen.x342));
wm.addView(view, superToast.getWindowParams());
}
//toast显示层级是activity级别,就使用外部提供的ViewGroup,层级和系统snackbar一样。
} else {
if (superToast.getViewGroup() == null) {
Log.e("ToastHandler", "displayToast: ViewGroup不能为空");
return;
}
try {
superToast.getViewGroup().addView(superToast.getView());
if (superToast.getShowAnimator() != null) {
Animator showAnimator = superToast.getShowAnimator();
animDuration = showAnimator.getDuration();
showAnimator.setTarget(superToast.getView());
showAnimator.start();
}
}catch (IllegalStateException e){
e.printStackTrace();
}
}
//如果不是一直显示就延迟取消
if (!superToast.isIndeterminate()) {
sendDelayedMessage(superToast, Messages.REMOVE_TOAST, superToast.getDuration() + animDuration);
}
}
/**
* 延迟发送消息
*/
private void sendDelayedMessage(SuperToast superToast, int what, long delay) {
Message message = obtainMessage(what);
message.obj = superToast;
sendMessageDelayed(message, delay);
}
/**
* 移除正在显示的toast。该方法会检索队列,如果队列中还有消息就会显示下一条。
*/
void removeToast(final SuperToast superToast) {
//移除队列第一条信息
mToastPriorityQueue.poll();
if (superToast.getDisplayLevel() == ToastStyle.LEVEL_SYSTEM) {
WindowManager wm = (WindowManager) superToast.getContext().getApplicationContext()
.getSystemService(Context.WINDOW_SERVICE);
if (wm != null) {
View view = superToast.getView();
if (view != null && ViewCompat.isAttachedToWindow(view)){
wm.removeView(view);
}
}
if (superToast.getDismissListener() != null) {
superToast.getDismissListener().onDismiss(superToast.getView());
}
//彻底隐藏有个时间,所以等到彻底隐藏在显示下一条
sendDelayedMessage(superToast, Messages.SHOW_NEXT, 250);
} else {
//如果改toast已经消失了,就不要再尝试让它消失。
if (!superToast.isShowing()) {
mToastPriorityQueue.remove(superToast);
return;
}
if (superToast.getHideAnimator() != null) {
Animator hideAnimator = superToast.getHideAnimator();
hideAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
dismiss(superToast);
}
});
hideAnimator.setTarget(superToast.getView());
hideAnimator.start();
}else {
dismiss(superToast);
}
}
}
private void dismiss(SuperToast superToast) {
if (superToast.getDismissListener() != null) {
superToast.getDismissListener().onDismiss(superToast.getView());
}
superToast.getViewGroup().removeView(superToast.getView());
showNextToast();
}
public void cancelAllToasts() {
removeMessages(Messages.SHOW_NEXT);
removeMessages(Messages.DISPLAY_TOAST);
removeMessages(Messages.REMOVE_TOAST);
for (SuperToast toast : mToastPriorityQueue) {
if (toast.isShowing()){
if (toast.getDisplayLevel() == ToastStyle.LEVEL_ACTIVITY){
try {
toast.getViewGroup().removeView(toast.getView());
}catch (NullPointerException | IllegalStateException e){
e.printStackTrace();
}
}else {
WindowManager wm = (WindowManager) toast.getContext().getApplicationContext()
.getSystemService(Context.WINDOW_SERVICE);
try {
wm.removeView(toast.getView());
}catch (NullPointerException | IllegalStateException e){
e.printStackTrace();
}
}
}
}
mToastPriorityQueue.clear();
}
/**
* 消息类型
*/
private static final class Messages {
/**
* 显示当前toast
*/
private static final int DISPLAY_TOAST = 101;
/**
* 显示下一条
*/
private static final int SHOW_NEXT = 102;
/**
* 取消
*/
private static final int REMOVE_TOAST = 103;
}
/**
* toast消息队列比较器,根据优先级排序。优先级一样就更加时间,先来后到顺序。
*/
private static class ToastComparator implements Comparator<SuperToast> {
@Override
public int compare(SuperToast o1, SuperToast o2) {
if (o1.isShowing()) {
return -1;
}
if (o1.getPriorityLevel() < o2.getPriorityLevel()) {
return -1;
} else if (o1.getPriorityLevel() > o2.getPriorityLevel()) {
return 1;
} else {
return o1.getTimestamp() <= o2.getTimestamp() ? -1 : 1;
}
}
}
}
/**
* toast工具类
* @author 己师
*/
public class ToastUtil {
private static SuperToast mToast;
/**
* 普通toast,就是默认样式
*/
public static void showNormal(Context context, String msg) {
SuperToast toast = new SuperToast(context)
.setMessage(msg)
.create()
.show();
}
/**
* 普通toast,就是默认样式
*/
public static void showNormal(Context context, @StringRes int resId) {
showNormal(context, ResUtil.getString(resId));
}
/**
* 只显示当前的toast,取消所有正在显示或等待显示的toast
*/
public static void showOnly(Context context, String msg) {
SuperToast toast = new SuperToast(context);
toast.cancelAllToasts();
toast.setMessage(msg)
.setDuration(ToastStyle.DURATION_LONG)
.create()
.show();
}
public static void showOnly(Context context, @StringRes int resId) {
showOnly(context, ResUtil.getString(resId));
}
/**
* 在当前页面显示toast。显示前会取消所有正在显示或等待显示的toast
*
* @param context 必须是activity
*/
public static void showOnActivity(Context context, String msg) {
SuperToast toast = new SuperToast(context);
toast.cancelAllToasts();
toast.setMessage(msg)
.setDuration(ToastStyle.DURATION_LONG)
.setDisplayLevel(ToastStyle.LEVEL_ACTIVITY)
.create().show();
}
/**
* 在当前页面显示toast。显示前会取消所有正在显示或等待显示的toast
*
* @param context 必须是activity
*/
public static void showOnActivity(Context context, int resId) {
showOnly(context, ResUtil.getString(resId));
}
public static void showInfo(Context context, String msg) {
//目前所有的toast的显示都一样
showOnly(context, msg);
}
public static void showInfo(Context context, int resId) {
//目前所有的toast的显示都一样
showOnly(context, ResUtil.getString(resId));
}
public static void showError(Context context, String msg) {
//目前所有的toast的显示都一样
showOnly(context, msg);
}
public static void showError(Context context, int resId) {
//目前所有的toast的显示都一样
showOnly(context, ResUtil.getString(resId));
}
/**
* 持久显示。只在当前activity里显示。退出页面就会消失
*/
public static void showIndefinite(Context context, String msg) {
if (mToast != null) {
mToast.dismiss();
}
mToast = new SuperToast(context)
.setMessage(msg)
.setDisplayLevel(ToastStyle.LEVEL_ACTIVITY)
.setRadius(80)
.setDuration(ToastStyle.DURATION_INDEFINITE)
.create()
.show();
}
/**
* 持久显示。只在当前activity里显示。退出页面就会消失
*/
public static void showIndefinite(Context context, int resId) {
if (mToast != null) {
mToast.dismiss();
}
mToast = new SuperToast(context)
.setMessage(resId)
.setDisplayLevel(ToastStyle.LEVEL_ACTIVITY)
.setRadius(80)
.setDuration(ToastStyle.DURATION_INDEFINITE)
.create()
.show();
}
public static void dismiss() {
if (mToast != null) {
mToast.dismiss();
mToast = null;
}
}
/**
* 持久显示。只在当前activity里显示。退出页面就会消失
*/
public static void showScene(Context context, View view) {
if (mToast != null) {
mToast.dismiss();
}
mToast = new SuperToast(context)
.setCanTouch(true)
.setView(view)
.setWidth(ResUtil.getDimen(R.dimen.x1000))
.setDisplayLevel(ToastStyle.LEVEL_SYSTEM)
.setGravity(Gravity.TOP)
.setXOffset(0)
.setYOffset(0)
.setRadius(80)
.setDuration(-1)
.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT)
.create()
.show();
}
}
使用方法
ToastUtil.showOnly(context, getString(R.string.un_subscribe_failed_str));
ToastUtil.showError(context, R.string.no_net_work_str);
ToastUtil.showInfo(getApplicationContext(), R.string.network_has_linked);