概述
前段时间接到一个需求,希望能够定制化Android Toast 的样式,于是稍微研究了下,并记录成文。
其实Github 上已经有了现成的很漂亮的第三方库,但是这样又要引入不少代码,稍显有些重,那到底Android 原生支不支持自定义Toast 样式呢?
原理
答案是肯定的。首先从Toast 的使用说起,我们一般都是makeText 这个方法来使用Toast,那么就从这个方法入手。
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
public static Toast makeText(Context context, CharSequence text, @Duration int duration{
Toast result = new Toast(context);
LayoutInflater inflate = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflate.inflate(com.android.internal.R.layout.transient_notification, null);
TextView tv = (TextView)v.findViewById(com.android.internal.R.id.message);
tv.setText(text);
result.mNextView = v;
result.mDuration = duration;
return result;
}
从这个方法中可以看到,这里首先是实例化了一个Toast 对象,然后inflate 一个布局,其子View 中包含一个TextView,我们的text 最后就是显示在这个TextView 上。看到这里,就应该可以想到接下来我们应该怎么做了,刚好屏幕往上滑看到了setView 这个方法,这不就是上面代码最后设置View 的方法么,那么接下来的事情就变得很简单了。
/**
* Set the view to show.
* @see #getView
*/
public void setView(View view) {
mNextView = view;
}
简单实现
public class ToastUtil {
private Toast mToast;
private Context mContext;
/**
* 修改原布局的Toast
*/
public ToastUtil(Context context) {
mContext = context;
mToast = new Toast(context);
View view = View.inflate(context, R.layout.toast_layout, null);
mToast.setView(view);
}
/**
* @param messageColor 文字的颜色
* @param backgroundColor 背景的颜色
* @return
*/
public ToastUtil setToastColor(int messageColor, int backgroundColor) {
View view = mToast.getView();
if (view != null) {
TextView message = ((TextView) view.findViewById(R.id.message));
view.setBackgroundColor(backgroundColor);
message.setTextColor(messageColor);
}
return this;
}
public ToastUtil shortTime() {
if (mToast == null) {
mToast = new Toast(mContext);
} else {
mToast.setDuration(Toast.LENGTH_SHORT);
}
return this;
}
/**
* 长时间显示Toast
*/
public ToastUtil longTime() {
if (mToast == null) {
mToast = new Toast(mContext);
} else {
mToast.setDuration(Toast.LENGTH_LONG);
}
return this;
}
public ToastUtil setMessage(String message) {
View view = mToast.getView();
TextView textView = (TextView) view.findViewById(R.id.message);
textView.setText(message);
return this;
}
public ToastUtil setMessage(@StringRes int message) {
View view = mToast.getView();
TextView textView = (TextView) view.findViewById(R.id.message);
textView.setText(mContext.getString(message));
return this;
}
public ToastUtil show() {
mToast.show();
return this;
}
/**
* 获取Toast
*
* @return
*/
public Toast getToast() {
return mToast;
}
}
上面的代码在构造函数中给Toast 设置了一个自定义的layout,其实如果单纯只是修改Toast 的背景或者文字颜色的话,可以直接使用默认的layout,但是在实际使用中发现某些设置上会将边距吃掉,仅仅只有文字,因此使用自定义的layout。
修改后的效果如下:
