android自定義Toast——讓你應用別具一格
實際上,在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);
總結
第三方框架為了靈活多樣式往往會增加設計的複雜度,自己的應用可以不用這樣靈活【應用有自己的風格,往往風格比較固定】,甚至在專案中犧牲一定的靈活性降低複雜度,更加簡潔,方便修改(比如如果替換佔位圖)。