Android 一文告訴你到底是用Dialog,Snackbar,還是Toast
Dialog和Toast,大家一定非常熟悉,常常被用來作為Android應用內提示性信息的兩種展示方式。然而Google在Design包中又提供了一種新的選擇,那就是Snackbar。這三種提示框到底有什么區別呢,使用時到底該如何選擇呢?不妨跟著本文一起學習一下吧。
Dialog
模態對話框。也就說,此刻該對話框中的內容獲取了焦點,想要操作對話框以外的功能,必須先對該對話框進行響應。
借助AlertDialog類可以快速實現一個Dialog的展示,注意Android中的AlertDialog采用了建造者模式,代碼如下:
public void onClickDialog(View v){
new AlertDialog.Builder(this)
.setTitle("Title")
.setMessage("This is message")
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setPositiveButton("Confirm", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.create()
.show();
}
效果如圖:

需要注意的是,不同版本的系統下,android.app.AlertDialog包中的AlertDialog展示樣式不太一樣。上圖是在6.0系統下展示的效果,屬于MD風格樣式。我們再看一下Android 4.4.4系統的默認樣式:

是不是很丑,大家可以自己嘗試,在更低版本中,系統Dialog的默認樣式更丑!不過值得慶幸的是,在V7包中,有AlertDialog的兼容版!大家在使用的時候可以使用android.support.v7.app.AlertDialog,這樣,就能夠在不同的版本中統一使用MD風格下的默認樣式的Dialog,就像圖一展示的那樣。
補充一點,在Android 5.0也就是Android L之后,Button的默認樣式會導致英文字母大寫,我們可以通過設置android:textAllCaps="false"屬性來處理這個問題。對于AlertDialog,可以操作Theme樣式,但有一點需要注意,就是在values文件夾theme中設置的時候不能直接使用這個屬性,會導致版本兼容問題,只要去掉android:命名空間即可,如:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/blue</item>
<item name="colorPrimaryDark">@color/blue_dark</item>
<item name="colorAccent">@color/red</item>
<item name="textAllCaps">false</item>
</style>
Toast
非模態提示框。也就說提示框的顯示并不影響我們對其他地方的操作,Toast無法手動控制隱藏,需要設置Toast的顯示時長,一旦顯示時間結束,Toast會自動消失。代碼如下:
public void onClickToast(View v){
Toast.makeText(this, "This is a Toast", Toast.LENGTH_SHORT).show();
}
顯示效果如圖:

Toast的使用也有一個需要注意的地方,由于Toast是非模態的,如果多次點擊并顯示Toast,就會出現Toast重復創建并顯示,給用戶造成一種Toast長時間不隱藏的幻覺,如圖:

顯然,這種現象非常影響用戶體驗,為了解決這種問題,我們可以對Toast的顯示做一個封裝,使用Static全局變量,建一個ToastUtils工具類,始終使用一個Toast顯示信息,代碼如下:
public class ToastUtils {
private static Toast toast;
public static void showToast(Context context, String message) {
if (toast == null) {
toast = Toast.makeText(context, message, Toast.LENGTH_SHORT);
} else {
toast.setText(message);
}
toast.show();
}
}
封裝之后,Toast顯示時長始終是我們設置的Toast.LENGTH_SHORT或Toast.LENGTH_LONG,如圖:

Snackbar
Snackbar是Design包中提出的一種介于Dialog和Toast之間的新控件。我們先來看一下它的使用代碼:
public void onClickSnackbar(View v){
Snackbar.make(this.findViewById(android.R.id.content), "This is a Snackbar", Snackbar.LENGTH_SHORT)
.setAction("Cancel", new View.OnClickListener() {
@Override
public void onClick(View v) {
}
})
.show();
}
可以看出,Snackbar的使用與Toast特別像,唯獨多了個setAction方法。這里需要說明一下make方法的第一個參數,是一個View對象,先看一下源碼介紹:
Snackbar will try and find a parent view to hold Snackbar's view from the value given to {@code view}. Snackbar will walk up the view tree trying to find a suitable parent, which is defined as a {@link CoordinatorLayout} or the window decor's content view,* whichever comes first.
也就是說,Snackbar將從這個View參數找出當前窗口最外層視圖,然后在其底部顯示。所以,如果當前是Activity,這個View可以是Activity中的任何一個元素,也可以像上面示例代碼中那樣,直接使用Activity的ContentView。Snackbar顯示效果如圖:

相比Toast,Snackbar多了個可操作的按鈕,并為其設置文本內容和監聽事件,用于手動控制彈框的隱藏。當然,也可以不設置按鈕,這種情況,Snackbar只能在到達顯示時長后自動隱藏,如圖:

小結
Dialog,Snackbar,Toast都可以作為應用內的一種提示框來使用,但從各自的特性來看,三者所表現出來的重要性為:Dialog > Snackbar > Toast 。所以,不同的應用場景下,選擇一個合適的方式來顯示提示性信息,對于提升用戶體驗來說,也是非常重要的。
-
對于刪除確認、版本更新等重要性提示信息,需要用戶做出選擇的情況下,使用Dialog;
-
對于無網絡提示、刪除成功、發布操作完成等這類不重要的提示性信息,使用Toast;
-
介于二者之間的其它情況,不妨使用Snackbar,給用戶一個多重選擇也許會是一個不錯的方式。
示例源碼
我在GitHub上建立了一個Repository,用來存放整個Android Material Design系列控件的學習案例,會伴隨著文章逐漸更新完善,歡迎大家補充交流,Star地址:
https://github.com/Mike-bel/MDStudySamples
來自:http://www.jianshu.com/p/9eb3b17b0e77