Android中Snackbar的使用方法及小技巧
前言
Snackbar和Toast相似,都是為了給用戶提供交互信息,Snackbar是固定在底部的,顯示時從下往上滑出

要使用Snackbar,需要在項目的build.gradle中添加依賴
dependencies {
compile 'com.android.support:design:23.4.0'
}
Snackbar的使用方法和Toast很相似
Snackbar.make(mOpenTv, "消息內(nèi)容", Snackbar.LENGTH_SHORT)
.setAction("確定", new View.OnClickListener() {
@Override
public void onClick(View v) {
}
})
.show();
第一個參數(shù)需要傳入一個View,可以是界面當中的任意一個View控件,Snackbar會自動根據(jù)這個控件找到最外層的布局來顯示
第二個參數(shù)就是我們需要顯示的內(nèi)容,注意這里的內(nèi)容最多顯示兩行哦,超出兩行后的內(nèi)容會變成“…”
第三個參數(shù)為Snackbar顯示的時長,有三種模式供選擇
- LENGTH_SHORT:短時間顯示
- LENGTH_LONG:長時間顯示
- LENGTH_INDEFINITE:一直顯示,只有當用戶觸發(fā)Action點擊事件或手動刪除時才會消失
Snackbar可以通過setAction方法設置一個點擊事件,和用戶進行交互
我們還可以通過setCallback方法來監(jiān)聽Snackbar的顯示和關閉
Snackbar sb = Snackbar.make(mOpenTv, "消息內(nèi)容", Snackbar.LENGTH_SHORT);
sb.setCallback(new Snackbar.Callback() {
@Override
public void onDismissed(Snackbar snackbar, int event) {
super.onDismissed(snackbar, event);
// Snackbar關閉時回調
}
@Override
public void onShown(Snackbar snackbar) {
super.onShown(snackbar);
// Snackbar打開時回調
}
});
sb.show();
Snackbar還支持滑出刪除,需要在布局文件中使用CoordinatorLayout作為根布局

建議要使用Snackbar的時候最好是以CoordinatorLayout作為根布局,如果以其它RelativeLayout,LinearLayout等作為根布局的話,會出現(xiàn)以下這種情況

FloatingActionButton被遮到了,使用CoordinatorLayout作為根布局可以避免這種情況

Snackbar只能在底部顯示嗎?
是也不是,為啥這么說呢,Snackbar確實是在CoordinatorLayout底部顯示的,但并不等于是在屏幕頂部
首先我們要知道Snackbar顯示的原理是什么
之前介紹中的第一個傳進去的參數(shù)View,Snackbar會通過這個View控件找到它所在的根布局,我們來查看下源碼
public static Snackbar make(@NonNull View view, @NonNull CharSequence text,
@Duration int duration) {
Snackbar snackbar = new Snackbar(findSuitableParent(view));
snackbar.setText(text);
snackbar.setDuration(duration);
return snackbar;
}
我們傳進去的view會經(jīng)過findSuitableParent方法的處理,我們再來看下這個方法的具體實現(xiàn)
private static ViewGroup findSuitableParent(View view) {
ViewGroup fallback = null;
do {
if (view instanceof CoordinatorLayout) {
// We've found a CoordinatorLayout, use it
return (ViewGroup) view;
} else if (view instanceof FrameLayout) {
if (view.getId() == android.R.id.content) {
// If we've hit the decor content view, then we didn't find a CoL in the
// hierarchy, so use it.
return (ViewGroup) view;
} else {
// It's not the content view but we'll use it as our fallback
fallback = (ViewGroup) view;
}
}
if (view != null) {
// Else, we will loop and crawl up the view hierarchy and try to find a parent
final ViewParent parent = view.getParent();
view = parent instanceof View ? (View) parent : null;
}
} while (view != null);
// If we reach here then we didn't find a CoL or a suitable content view so we'll fallback
return fallback;
}
詳細的過程google的工程師已經(jīng)寫的非常的清楚了,我們主要需要了解的就是當一個View的直接父布局為CoordinatorLayout時,就以這個CoordinatorLayout為標準來顯示Snackbar
我們可以做個小實驗驗證一下
在傳入的View控件外面套一層CoordinatorLayout
<android.support.design.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="100dp"> <TextView android:id="@+id/tv_open_snackbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="打開Snackbar" android:textSize="28sp"/> </android.support.design.widget.CoordinatorLayout>
再運行一下看看,效果就變成了下面這樣

所以說Snackbar的顯示位置還是可以通過這個小技巧來改變的
如果嫌默認的Snackbar太丑怎么辦?
我們可以來自定義它的外觀
1.改變按鈕的文字顏色
通過調用setActionTextColor方法即可改變按鈕的文字顏色
Snackbar sb = Snackbar.make(mOpenTv, "消息內(nèi)容", Snackbar.LENGTH_SHORT);
sb.setAction("確定", new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
sb.setActionTextColor(Color.YELLOW);
sb.show();

2.改變消息內(nèi)容的文字顏色
Snackbar沒有給我們提供改變消息文本顏色的api接口,但在查看源碼時發(fā)現(xiàn)了這個方法getView
/**
* Returns the {@link Snackbar}'s view.
*/
@NonNull
public View getView() {
return mView;
}
這里返回的mView其實是一個SnackbarLayout布局,在SnackbarLayout的構造方法中找到了它的布局文件design_layout_snackbar_include
// Now inflate our content. We need to do this manually rather than using an <include> // in the layout since older versions of the Android do not inflate includes with // the correct Context. LayoutInflater.from(context).inflate(R.layout.design_layout_snackbar_include, this);
design_layout_snackbar_include布局文件里只有兩個控件,一個TextView,一個Button
<merge xmlns:android="http://schemas.android.com/apk/res/android"> <TextView android:id="@+id/snackbar_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:paddingTop="@dimen/design_snackbar_padding_vertical" android:paddingBottom="@dimen/design_snackbar_padding_vertical" android:paddingLeft="@dimen/design_snackbar_padding_horizontal" android:paddingRight="@dimen/design_snackbar_padding_horizontal" android:textAppearance="@style/TextAppearance.Design.Snackbar.Message" android:maxLines="@integer/design_snackbar_text_max_lines" android:layout_gravity="center_vertical|left|start" android:ellipsize="end" android:textAlignment="viewStart"/> <Button android:id="@+id/snackbar_action" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/design_snackbar_extra_spacing_horizontal" android:layout_marginStart="@dimen/design_snackbar_extra_spacing_horizontal" android:layout_gravity="center_vertical|right|end" android:paddingTop="@dimen/design_snackbar_padding_vertical" android:paddingBottom="@dimen/design_snackbar_padding_vertical" android:paddingLeft="@dimen/design_snackbar_padding_horizontal" android:paddingRight="@dimen/design_snackbar_padding_horizontal" android:visibility="gone" android:textColor="?attr/colorAccent" style="?attr/borderlessButtonStyle"/> </merge>
相信看到這里大家應該知道怎么做了,TextView的id為snackbar_text,我們通過getView()來獲取這個TextView控件
Snackbar sb = Snackbar.make(mOpenTv, "消息內(nèi)容", Snackbar.LENGTH_SHORT);
sb.setAction("確定", new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
sb.setActionTextColor(Color.YELLOW);
View view = sb.getView();
TextView tv = (TextView) view.findViewById(R.id.snackbar_text);
tv.setTextColor(Color.RED);
sb.show();

同樣的,我們也可以通過tv.setTextSize設置它的文字大小
3.改變消息內(nèi)容的背景
同理,根據(jù)以上方法,得到它的布局,調用對應的api接口就好
View view = sb.getView(); view.setBackgroundColor(Color.RED);
像這種紅紅的給用戶警告的提示,是不是比Toast要來的炫酷多了呢


4.給消息內(nèi)容添加圖標
獲取到消息內(nèi)容的TextView后,調用setCompoundDrawables方法設置它的圖標,可自由選擇圖標放置的位置,四個參數(shù)分別對應TextView的左、上、右、下
Snackbar sb = Snackbar.make(mOpenTv, "消息內(nèi)容", Snackbar.LENGTH_SHORT);
sb.setAction("確定", new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
sb.setActionTextColor(Color.YELLOW);
View view = sb.getView();
TextView tv = (TextView) view.findViewById(R.id.snackbar_text);
Drawable d = ContextCompat.getDrawable(this, R.drawable.warn);
d.setBounds(0, 0, d.getMinimumWidth(), d.getMinimumHeight());
tv.setCompoundDrawables(d, null, null, null); // 給TextView左邊添加圖標
tv.setGravity(Gravity.CENTER); // 讓文字居中
sb.show();
}

注意要設置setGravity使其居中,不然文字默認在上面不好看啊
就先介紹這么多,其實只要拿到了它的布局,接下來怎么整就看各位的喜好啦
總結
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關文章
Android EditText監(jiān)聽回車鍵并處理兩次回調問題
這篇文章主要介紹了Android EditText監(jiān)聽回車鍵并處理兩次回調問題,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08
Android 圖片處理避免出現(xiàn)oom的方法詳解
本篇文章主要介紹了Android 圖片處理避免出現(xiàn)oom的方法詳解,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09
Android4.4下MediaProvider無法向外置SD卡中文件寫數(shù)據(jù)的解決方法
這篇文章主要介紹了Android4.4下MediaProvider無法向外置SD卡中文件寫數(shù)據(jù)的解決方法,實例分析了Android4.4下針對讀寫限制的修改技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-10-10
詳解Activity之singletast啟動模式及如何使用intent傳值
在一個新棧中創(chuàng)建該Activity實例,并讓多個應用共享改棧中的該Activity實例。一旦改模式的Activity的實例存在于某個棧中,任何應用再激活改Activity時都會重用該棧中的實例,其效果相當于多個應用程序共享一個應用,不管誰激活該Activity都會進入同一個應用中2015-11-11

