1. 程式人生 > >Android 自定義Toast,修改Toast樣式和顯示時長

Android 自定義Toast,修改Toast樣式和顯示時長

Android 中有一個 Toast 控制元件,可以用來顯示提示資訊,還是非常好用的,但是樣式和顯示時長比較侷限。所以我們來自定義一個 

Toast ,讓它可以顯示我們想要的效果,並能設定顯示時長。

首先,在 res\layout 資料夾下建立自定義 Toast 的佈局檔案 custom_toast.xml,用來設定 Toast 的樣式:

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:id
    ="@+id/toast_custom_parent"
  4.     android:layout_width="fill_parent"
  5.     android:layout_height="fill_parent"
  6.     android:orientation="vertical">
  7.     <TextView
  8.         android:id="@+id/tvToastContent"
  9.         android:layout_width="wrap_content"
  10.         android:layout_height="46dp"
  11.         android:layout_marginBottom
    ="75dp"
  12.         android:background="@drawable/toast_customer_style"
  13.         android:gravity="center"
  14.         android:textColor="#FFFFFF"/>
  15. </LinearLayout>
這裡的自定義 Toast 其實就是一個TextView ,其中引用了 res\drawable 資料夾下的一個 shape 樣式檔案:
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <shapexmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:shape="rectangle">
  4.     <!-- 設定背景透明度和顏色 -->
  5.     <solidandroid:color="#99000000"/>
  6.     <!-- 設定四個角為弧形 -->
  7.     <cornersandroid:radius="23dp"/>
  8.     <padding
  9.         android:left="23dp"
  10.         android:right="23dp"/>
  11. </shape>
到這裡,所有的佈局就已經設計好了,也就是實現了自定義樣式,接下來就是在程式碼中實現自定義 Toast 了,以及實現設定顯示時

長:

  1. publicclass CustomToast {  
  2.     privateboolean canceled = true;  
  3.     private Handler handler;  
  4.     private Toast toast;  
  5.     private TimeCount time;  
  6.     private TextView toast_content;  
  7.     public CustomToast(Context context, ViewGroup viewGroup) {  
  8.         this(context, viewGroup, new Handler());  
  9.     }  
  10.     public CustomToast(Context context, ViewGroup viewGroup, Handler handler) {  
  11.         this.handler = handler;  
  12.         View layout = LayoutInflater.from(context).inflate(R.layout.custom_toast, viewGroup);  
  13.         toast_content = (TextView) layout.findViewById(R.id.tvToastContent);  
  14.         if (toast == null) {  
  15.             toast = new Toast(context);  
  16.         }  
  17.         toast.setGravity(Gravity.BOTTOM, 00);  
  18.         toast.setDuration(Toast.LENGTH_LONG);  
  19.         toast.setView(layout);  
  20.     }  
  21.     /** 
  22.      * @param text     要顯示的內容 
  23.      * @param duration 顯示的時間長 
  24.      *                 根據LENGTH_MAX進行判斷 
  25.      *                 如果不匹配,進行系統顯示 
  26.      *                 如果匹配,永久顯示,直到呼叫hide() 
  27.      */
  28.     publicvoid show(String text, int duration) {  
  29.         time = new TimeCount(duration, 1000);  
  30.         toast_content.setText(text);  
  31.         if (canceled) {  
  32.             time.start();  
  33.             canceled = false;  
  34.             showUntilCancel();  
  35.         }  
  36.     }  
  37.     /** 
  38.      * 隱藏Toast 
  39.      */
  40.     publicvoid hide() {  
  41.         if (toast != null) {  
  42.             toast.cancel();  
  43.         }  
  44.         canceled = true;  
  45.     }  
  46.     privatevoid showUntilCancel() {  
  47.         if (canceled) {  
  48.             return;  
  49.         }  
  50.         toast.show();  
  51.         handler.postDelayed(new Runnable() {  
  52.             publicvoid run() {  
  53.                 showUntilCancel();  
  54.             }  
  55.         }, 3000);  
  56.     }  
  57.     /** 
  58.      * 計時器 
  59.      */
  60.     class TimeCount extends CountDownTimer {  
  61.         public TimeCount(long millisInFuture, long countDownInterval) {  
  62.             super(millisInFuture, countDownInterval); // 總時長,計時的時間間隔
  63.         }  
  64.         @Override
  65.         publicvoid onFinish() { // 計時完畢時觸發
  66.             hide();  
  67.         }  
  68.         @Override
  69.         publicvoid onTick(long millisUntilFinished) { // 計時過程顯示
  70.         }  
  71.     }  
  72. }  

這裡主要通過一個倒計時器和非同步執行緒來實現設定顯示時長。TimeCount 有兩個引數,第一個是倒計時時長,也就是 Toast 要顯示

的時長,第二個是間隔時間,在倒計時內每隔一定時間會回撥一次 onTick 方法,倒計時結束後回撥 onFinish 方法。在倒計時器中我 

們要設定的只有倒計時時長,即顯示時長,時間到了就 cancel() 掉 Toast。在對 Toast 初始化時,預設設定的顯示時長是

LENGTH_LONG ,大約為3s,那麼問題來了,3s以內倒計時器可以控制顯示時長,但是超過3s Toast 就自行結束了,如果我們想

要顯示超過三秒怎麼辦,所以這裡通過一個非同步執行緒,並設定一個 postDelayed 任務,推遲3s執行,線上程中呼叫自身的方法,實

現迴圈呼叫。 這樣每隔3s顯示一次 Toast ,達到了一直顯示的效果。然後通過 canceled 屬性,將倒計時器和非同步執行緒聯絡到一起,

這樣就可以通過 Handler 讓 Toast 一直顯示,再通過 TimeCount 讓 Toast 結束顯示,達到了自定義顯示時長的效果。

具體呼叫方法如下:

  1. private CustomToast toast;  
  2. privatevoid toastMessage(String content) {  
  3.     if (toast != null) {  
  4.         toast.hide();  
  5.     }  
  6.     toast = new CustomToast(LoginActivity.this,  
  7.             (ViewGroup) this.findViewById(R.id.toast_custom_parent));  
  8.     toast.show(content, 500);  
  9. }  
這樣我們就可以在 onClick 等事件中通過呼叫 toastMessage("自定義 Toast 的顯示內容 "); 來顯示你想要給使用者看到的提示內容了。