测试自定义Toast时遇到的一个小Bug,在自定义类中写有两种Toast的对象,这个对象分别在自带的方法和自定义布局的方法使用,也就是说同一个自定义Toast类中不可以非自定义布局和自定义布局共同使用一个Toast对象,需要分开使用Toast对象,不然会报错的。
解决方法:非自定义布局和自定义布局(自己写弹框布局的)不使用同一个Toast对象,(使用相对于的两个对象)
下面看看最终的自定义类:
/**
* SGF
* 自定义土司工具类
*/
public class ToastUtils {
private static String oldMsg;
/**
* 纯文字Toast
*/
protected static Toast toast = null;
/**
* 自定义View的Toast
*/
protected static Toast mViewToast = null;
private static long oneTime = 0;
private static long twoTime = 0;
/**
* 全局上下位
*/
private static Context mContext = MyApplication.getContextObject();
// private static int locationType = 0;
/**
* Toast引用布局所需要的inflater
*/
private static LayoutInflater inflater;
/**
* Toast所引用的布局
*/
private static View layout;
/**
* Toast显示的文本
*/
private static TextView toast_text;
/**
* Toast所显示的图片
*/
private static ImageView toast_img;
//显示时间长
public static void showLong(Context context, String text, int locationType) {
show(context, text, Toast.LENGTH_LONG, locationType);
}
//显示时间短
public static void showShort(Context context, String text, int locationType) {
show(context, text, Toast.LENGTH_SHORT, locationType);
}
//显示时间短-自定义布局
public static void showShortCustomize(Context context, String text, int locationType) {
initToast(context, text, locationType);
}
/**
* 纯文字吐司
*
* @param mContext
* @param msg
* @param mode
* @param locationType
*/
private static void show(Context mContext, String msg, int mode, int locationType) {
cancelToast();
if (toast == null) {
//这样的话,不管传递什么content进来,都只会引用全局唯一的Content,不会产生内存泄露
toast = Toast.makeText(mContext.getApplicationContext(), msg, Toast.LENGTH_SHORT);
// //设置吐司的显示位置
setLocationType(locationType);
toast.show();
oneTime = System.currentTimeMillis();
} else {
toast = Toast.makeText(mContext.getApplicationContext(), msg, Toast.LENGTH_SHORT);
twoTime = System.currentTimeMillis();
// //设置吐司的显示位置
setLocationType(locationType);
if (msg.equals(oldMsg)) {
if (twoTime - oneTime > mode) {
toast.show();
}
} else {
oldMsg = msg;
toast.setText(msg);
toast.show();
}
}
oneTime = twoTime;
}
/**
* @param mContext
* @param layoutId 自定义布局
* @param str
* @param showTime
*/
private void midToast(Context mContext, int layoutId, String str, int showTime) {
cancelToast();
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//自定义布局
View view = inflater.inflate(layoutId, null);
// ImageView img_logo = (ImageView) view.findViewById(R.id.img_logo);
// TextView tv_msg = (TextView) view.findViewById(R.id.tv_msg);
// tv_msg.setText(str);
Toast toast = new Toast(mContext);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(view);
toast.show();
}
/**
* 初始化Toast
*
* @param mContext 上下文
* @param text 显示的文本
*/
private static void initToast(Context mContext, CharSequence text, int locationType) {
try {
//https://www.jianshu.com/p/60f2b8339902
//注意自定义的toast对象不可以与其它的toast共用一个对象,会报异常
cancelViewToast();
mViewToast = Toast.makeText(mContext.getApplicationContext(), text, Toast.LENGTH_SHORT);
// 获取LayoutInflater对象
inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// 由layout文件创建一个View对象
layout = inflater.inflate(R.layout.toast_layout, null);
// 吐司上的图片
toast_img = layout.findViewById(R.id.toast_img);
//设置图标动画
ObjectAnimator.ofFloat(toast_img, "rotationY", 30, 180, 0)
.setDuration(1000).start();
// 实例化ImageView和TextView对象
toast_text = layout.findViewById(R.id.toast_text);
toast_text.setText(text);
mViewToast.setView(layout);
setViewLocationType(locationType);
// mViewToast.setGravity(Gravity.CENTER, 0, 70);
mViewToast.show();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 设置吐司显示的位置方法
*/
private static void setLocationType(int locationType) {
//设置吐司的显示位置
if (locationType == 0) {//上
toast.setGravity(Gravity.TOP, 0, 0);
} else if (locationType == 1) {//下
toast.setGravity(Gravity.BOTTOM, 0, 70);
} else if (locationType == 2) {//左
toast.setGravity(Gravity.LEFT, 0, 0);
} else if (locationType == 3) {//右
toast.setGravity(Gravity.RIGHT, 0, 0);
} else if (locationType == 4) {//中
toast.setGravity(Gravity.CENTER, 0, 0);
} else if (locationType == 5) {//
toast.setGravity(Gravity.CENTER_HORIZONTAL, 0, 0);
} else if (locationType == 6) {//
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
}
}
/**
* 设置自定义布局吐司显示的位置方法
*/
private static void setViewLocationType(int locationType) {
//设置吐司的显示位置
if (locationType == 0) {//上
mViewToast.setGravity(Gravity.TOP, 0, 0);
} else if (locationType == 1) {//下
mViewToast.setGravity(Gravity.BOTTOM, 0, 70);
} else if (locationType == 2) {//左
mViewToast.setGravity(Gravity.LEFT, 0, 0);
} else if (locationType == 3) {//右
mViewToast.setGravity(Gravity.RIGHT, 0, 0);
} else if (locationType == 4) {//中
mViewToast.setGravity(Gravity.CENTER, 0, 0);
} else if (locationType == 5) {//
mViewToast.setGravity(Gravity.CENTER_HORIZONTAL, 0, 0);
} else if (locationType == 6) {//
mViewToast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
}
}
/**
* 隐藏当前Toast
*/
public static void cancelToast() {
if (toast != null) {
toast.cancel();
}
}
/**
* 隐藏当前Toast
*/
public static void cancelViewToast() {
if (mViewToast != null) {
mViewToast.cancel();
}
}
}
自定义全局上下文:
/**
* 编写自定义Application,管理全局状态信息,比如Context
*
*/
public class MyApplication extends Application {
private static Context context;
@Override
public void onCreate() {
super.onCreate();
//获取Context
context = getApplicationContext();
}
//返回
public static Context getContextObject(){
return context;
}
}
调用方法:
ToastUtils.showShort(this,"这是纯文本Toast",1);
布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/toast_back"
android:gravity="center_vertical"
android:orientation="vertical"
android:padding="13dp">
<ImageView
android:id="@+id/toast_img"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="5dp"
android:background="@drawable/toast_y" />
<TextView
android:id="@+id/toast_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:gravity="center"
android:text="加入购物车失败"
android:textColor="@color/colorWhite"
android:textSize="17sp" />
<TextView
android:id="@+id/toast_sub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:gravity="center"
android:textColor="@color/colorWhite"
android:textSize="12sp"
android:visibility="gone" />
</LinearLayout>
相关吐司弹框提示链接:
https://github.com/Bamboy120315/bamboy
https://github.com/Ericsongyl/AndroidToastUtil
https://github.com/GrenderG/Toasty
https://github.com/getActivity/ToastUtils
https://github.com/JohnPersano/SuperToasts
https://github.com/Muddz/StyleableToast
https://github.com/PureWriter/ToastCompat
https://github.com/Shashank02051997/FancyToast-Android
https://github.com/SwiftyWang/ToastBar
https://github.com/Dovar66/DToast
https://github.com/bboylin/UniversalToast
https://github.com/johnkil/Android-AppMsg
https://github.com/the-pig-of-jungle/smart-show
https://github.com/pyricau/frenchtoast
https://github.com/Pierry/SimpleToast
Dialog、PopupWindow加载弹框链接:
https://github.com/ydxlt/LoadingDialog
https://github.com/kakajika/RelativePopupWindow
https://github.com/zyyoona7/EasyPopup
https://github.com/zyyoona7/EasyPopup
https://github.com/douglasjunior/android-simple-tooltip
https://github.com/tianzhijiexian/EasyDialog
http://liangjingkanji.coding.me/2017/02/11/PopupWindow/
https://github.com/orhanobut/dialogplus
https://github.com/kongzue/Dialog
https://github.com/kongzue/DialogV3
https://github.com/sd6352051/NiftyDialogEffects
https://github.com/hss01248/DialogUtil
https://github.com/yipianfengye/android-adDialog
https://github.com/Alex-Cin/Dialog
https://github.com/H07000223/FlycoDialog_Master
https://github.com/tvbarthel/BlurDialogFragment
https://github.com/JZXiang/TimePickerDialog
https://github.com/d-max/spots-dialog
https://github.com/shaohui10086/BottomDialog
https://github.com/yarolegovich/LovelyDialog
https://github.com/michaelye/EasyDialog
https://github.com/Qiang3570/Dialog
https://github.com/javiersantos/MaterialStyledDialogs
https://github.com/javiersantos/BottomDialogs
https://github.com/lewisjdeane/L-Dialogs
https://github.com/lingcimi/jjdxm_dialogui
https://github.com/pinguo-zhouwei/CustomPopwindow
https://github.com/HMY314/PopWindow
https://github.com/tonycheng93/PopWindow
https://github.com/Jay-Goo/MultiSelectPopWindow
https://github.com/PangHaHa12138/ManyPopWindowAndDialog
https://github.com/jdsjlzx/PopWindowMeituan
https://github.com/2223512468/PopAndroid
https://github.com/ccj659/PopsTabView
https://github.com/haiyuKing/SpinnerViewPopDemo
https://github.com/MazohMa/basePopWindow
https://github.com/beilly/randomkeyboard
https://github.com/houshuai0816/PopWindow
https://github.com/newPersonKing/PopWindow
https://github.com/wuyunqiang/AndroidToRN
https://github.com/xyzlf/PopManager
https://github.com/nanyuweiyi/SelectPopwindow
https://github.com/nesger/WechatPopupWindow
https://github.com/caocao123/EditTextPopWindow
https://github.com/stoneWangL/PopWindowSoftInput
https://github.com/jiaowenzheng/CustomSeekBar
https://github.com/NikoSoftware/FrameModel
https://github.com/lixiaoming0314/popwindow
https://github.com/AngelGong/SideBar