实际上,在github上层看到这种toast,但我的感觉是:用起来太麻烦了!我需要的要求是越简单越好!
简化Toast
- 原toast形式:
Toast.makeText(this,”t”,Toast.LENGTH_LONG).show();或Toast.makeText(this,”t”,Toast.LENGTH_SHORT).show();
- 简化后: ToastUtil.shorts(“t”); ToastUtil.longs(“t”); 这样才方便简单。
1.简化为两参
这一步很简单,只需要这样:
public class ToastUtil{
public static void shorts(Context context,String msg){
Toast.makeText(context,msg,Toast.LENGTH_SHORT).show();
}
public static void longs(Context context,String msg){
Toast.makeText(context,msg,Toast.LENGTH_LONG).show();
}
}
2.简化为一参
- 自定义Application
这个需要自定义application,假设为MyApp:
manifest中设置:
<application
android:name=".MyApp"
>
</application>
在项目根目录创建类:
public class MyApp extends Application{
private static MyApp mApp;
@Override
public void onCreate() {
super.onCreate();
mApp = this;
}
public static void getApp(){
return mApp;
}
}
更改ToastUtil
public class ToastUtil{
public static void shorts(String msg){
Toast.makeText(MyApp.getApp(),msg,Toast.LENGTH_SHORT).show();
}public static void longs(String msg){
Toast.makeText(MyApp.getApp(),msg,Toast.LENGTH_LONG).show();
}
}
自定义toast
然后你会发现,系统提供的toast又没特色,字又小,不使用图标确实又不好看,用户很可能在还没有关注到的时候,信息已经消失了,这个时候我们就要自定义toast.
1.改变字的大小和背景样式
修改前:
修改后:
2.自定义布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/linear_outter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="18dp"
android:background="@drawable/bg_toast"
android:padding="10dp"
android:orientation="vertical">
<TextView
android:id="@+id/txt_toast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textColor="@color/white"
android:gravity="center_vertical"
/>
</LinearLayout>
背景:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="30dp"/>
<solid android:color="#88000000"/>
</shape>
自定义类,用于修改toast显示效果
public class CustomToast{
private static void longs(String message){
//加载Toast布局
View toastRoot = LayoutInflater.from(AppUtils.getSuperContext()).inflate(R.layout.view_toast, null);
//初始化布局控件
mTextView = (TextView) toastRoot.findViewById(R.id.txt_toast);
//为控件设置属性
mTextView.setText(message);
//Toast的初始化
Toast toastStart = new Toast(AppUtils.getSuperContext());
//获取屏幕高度
WindowManager wm = (WindowManager) AppUtils.getSuperContext().getSystemService(Context.WINDOW_SERVICE);
int height = wm.getDefaultDisplay().getHeight();
//Toast的Y坐标是屏幕高度的2/3,不会出现不适配的问题
toastStart.setGravity(Gravity.TOP, 0, height / 3*2);
toastStart.setDuration(Toast.LENGTH_LONG);
toastStart.setView(toastRoot);
toastStart.show();
}
private static void shorts(String message){
//加载Toast布局
View toastRoot = LayoutInflater.from(AppUtils.getSuperContext()).inflate(R.layout.view_toast, null);
//初始化布局控件
mTextView = (TextView) toastRoot.findViewById(R.id.txt_toast);
//为控件设置属性
mTextView.setText(message);
//Toast的初始化
Toast toastStart = new Toast(AppUtils.getSuperContext());
//获取屏幕高度
WindowManager wm = (WindowManager) AppUtils.getSuperContext().getSystemService(Context.WINDOW_SERVICE);
int height = wm.getDefaultDisplay().getHeight();
//Toast的Y坐标是屏幕高度的2/3,不会出现不适配的问题,这个比例可根据喜好更改
toastStart.setGravity(Gravity.TOP, 0, height / 3*2);
toastStart.setDuration(Toast.LENGTH_SHORT);
toastStart.setView(toastRoot);
toastStart.show();
}
}
好吧,这段代码冗余的太多了,我们合并一下:
public class CustomToast{
private static void longs(String message){
message(true,message);
}
private static void shorts(String message){
message(false,message);
}
private static void message(boolean isLong,String message){
//加载Toast布局
View toastRoot = LayoutInflater.from(AppUtils.getSuperContext()).inflate(R.layout.view_toast, null);
//初始化布局控件
mTextView = (TextView) toastRoot.findViewById(R.id.txt_toast);
//为控件设置属性
mTextView.setText(message);
//Toast的初始化
Toast toastStart = new Toast(AppUtils.getSuperContext());
//获取屏幕高度
WindowManager wm = (WindowManager) AppUtils.getSuperContext().getSystemService(Context.WINDOW_SERVICE);
int height = wm.getDefaultDisplay().getHeight();
//Toast的Y坐标是屏幕高度的2/3,不会出现不适配的问题
toastStart.setGravity(Gravity.TOP, 0, height / 3*2);
toastStart.setDuration(isLong?Toast.LENGTH_LONG:Toast.LENGTH_SHORT);
toastStart.setView(toastRoot);
toastStart.show();
}
}
修改一下ToastUtil的代码:
public class ToastUtil {
public static void shorts(String msg){
CustomToast.shorts(msg);
}
public static void longs(String msg){
CustomToast.longs(msg);
}
}
这样就可以了,原有外部调用ToastUtil的代码可以不用变,这是我使用这个ToastUtil中间类而非直接使用CustomToast的原因,以后修改CustomToast可以不用影响主程序代码。
3.增加不同颜色标识不同的toast
可以看到,这些和普通toast的区别是背景变了,左侧的icon也有变化,图标大家可以在iconfont自己下载,这里写一下三个颜色供读者参考:红-E75427 橙-FF8800 绿-1DB34A
贴一下新的CustomToast和ToastUtil:
CustomToast.java
public class CustomToast {
private static DrawTextView mTextView;
public static void longs(String message) {
message(true,message);
}
public static void shorts(String message) {
message(false,message);
}
private static void message(boolean longMsg,String message){
message(longMsg,MSG_NORMAL,message);
}
public static void info(String message) {
message(true,MSG_INFO,message);
}
public static void sucess(String message) {
message(true,MSG_SUCESS,message);
}
public static void error(String message) {
message(true,MSG_ERROR,message);
}
public static void shortInfo(String message){
message(false,MSG_INFO,message);
}
public static void shortSuccess(String message){
message(false,MSG_SUCESS,message);
}
public static void shortError(String message){
message(false,MSG_ERROR,message);
}
private static final int MSG_NORMAL = 1;
private static final int MSG_INFO = 2;
private static final int MSG_SUCESS = 3;
private static final int MSG_ERROR = 4;
private static void message(boolean longMsg,int mode,String message){
//加载Toast布局
View toastRoot = LayoutInflater.from(AppUtils.getSuperContext()).inflate(R.layout.view_toast, null);
if(mode!=MSG_NORMAL){
toastRoot.setBackgroundResource(getBGIdByMode(mode));
}
//初始化布局控件
mTextView = (DrawTextView) toastRoot.findViewById(R.id.txt_toast);
//为控件设置属性
mTextView.setText(message);
if(mode!=MSG_NORMAL){
mTextView.setDraw(getIconByMode(mode));
}
//Toast的初始化
Toast toastStart = new Toast(AppUtils.getSuperContext());
//获取屏幕高度
WindowManager wm = (WindowManager) AppUtils.getSuperContext().getSystemService(Context.WINDOW_SERVICE);
int height = wm.getDefaultDisplay().getHeight();
//Toast的Y坐标是屏幕高度的2/3,不会出现不适配的问题
toastStart.setGravity(Gravity.TOP, 0, height / 3*2);
toastStart.setDuration(longMsg?Toast.LENGTH_LONG:Toast.LENGTH_SHORT);
toastStart.setView(toastRoot);
toastStart.show();
}
private static int getIconByMode(int mode) {
switch (mode){
case MSG_INFO:
return R.drawable.ic_toast_info;
case MSG_SUCESS:
return R.drawable.ic_toast_pass;
case MSG_ERROR:
return R.drawable.ic_toast_fail;
}
return 0;
}
private static int getBGIdByMode(int mode) {
switch (mode){
case MSG_INFO:
return R.drawable.bg_toast_info;
case MSG_SUCESS:
return R.drawable.bg_toast_success;
case MSG_ERROR:
return R.drawable.bg_toast_error;
}
return 0;
}
}
public class ToastUtil {
public static void shorts(String msg){
CustomToast.shorts(msg);
}
public static void longs(String msg){
CustomToast.longs(msg);
}
public static void info(String msg){
CustomToast.info(msg);
}
public static void success(String msg){
CustomToast.sucess(msg);
}
public static void error(String msg){
CustomToast.error(msg);
}
public static void sInfo(String msg){
CustomToast.shortInfo(msg);
}
public static void sSuccess(String msg){
CustomToast.shortSuccess(msg);
}
public static void sError(String msg){
CustomToast.shortError(msg);
}
}
使用:
ToastUtil.shorts("xx");//普通短消息
ToastUtil.longs("xx");//普通长消息
ToastUtil.info("xx");//提醒短消息
ToastUtil.sInfo("xx");//提醒长消息
ToastUtil.success("xx");//操作成功短消息
ToastUtil.sSucess("xx");//操作成功长消息
ToastUtil.error("xx");//操作失败短消息
ToastUtil.sError("xx");//操作失败长消息
是不是超超超简单呢?然而很好用!在一个应用内,我们的toast只需要一种风格足够。在开发中我往往纠结于为什么每次想着增加灵活度的时候,都意味着更复杂的代码。实际上,很多时候我们只需要一种风格,这种灵活度却增加了代码冗余。比如使用Glide进行图片显示,实际上我并不想每次都这样写:
Glide.with(context)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.placeholder(R.drawable.place)
.into(holder.img_product);
真的相当的麻烦,进行图片处理一个应用实际上只需要2-3种调用形式就足够了:
public class PicUtil{
private int defaultDraw = R.drawable.place;
public static void showCachePic(String url,View target){
Glide.with(MyApp.getApp())
.load(url)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.placeholder(defaultDraw )
.into(target);
}
public static void showPic(String url,View target){
Glide.with(MyApp.getApp())
.load(url)
.placeholder(defaultDraw)
.into(target);
}
}
于是,我下次可以直接写:PicUtil.showCachePic(url,target);
总结
第三方框架为了灵活多样式往往会增加设计的复杂度,自己的应用可以不用这样灵活【应用有自己的风格,往往风格比较固定】,甚至在项目中牺牲一定的灵活性降低复杂度,更加简洁,方便修改(比如如果替换占位图)。