实际上,在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
  • 更改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.改变字的大小和背景样式

修改前:

android自定义Toast——让你应用别具一格_android


修改后:

android自定义Toast——让你应用别具一格_初始化_02

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

android自定义Toast——让你应用别具一格_android_03

android自定义Toast——让你应用别具一格_初始化_04

android自定义Toast——让你应用别具一格_屏幕高度_05

可以看到,这些和普通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);

总结

第三方框架为了灵活多样式往往会增加设计的复杂度,自己的应用可以不用这样灵活【应用有自己的风格,往往风格比较固定】,甚至在项目中牺牲一定的灵活性降低复杂度,更加简洁,方便修改(比如如果替换占位图)。