Material Design系列文章(SnakeBar學習筆記)
1、SnakeBar基本使用
Snackbar.make(activity_main,"今天週五啦!",Snackbar.LENGTH_SHORT)
.setAction("確定", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"確定",Toast.LENGTH_SHORT).show();
}
}).addCallback(new BaseTransientBottomBar.BaseCallback<Snackbar>() {
//SnakeBar顯示的 時候調用
@Override
public void onShown(Snackbar transientBottomBar) {
super.onShown(transientBottomBar);
}
//SnakeBar隱藏的時候調用
@Override
public void onDismissed(Snackbar transientBottomBar, int event) {
super.onDismissed(transientBottomBar, event);
}
}).show();
2、SnakeBar可疊加多個Action,但是隻對最後一個Action有效
3、可以使用setActionTextColor()方法設置Action文字的的顏色
4、若想修改SnakeBar的文字的樣式,則需要通過獲取SnakeBar對象,然後獲得其對應的TextView(其id爲snackbar_text,具體可以看一下源碼的xml文件,裏面就是一個TextView和一個Button),對其修改部分屬性,如:修改文字顏色:
Snackbar bar = Snackbar.make(activity_main,"今天週五啦!",Snackbar.LENGTH_SHORT).setAction("確定", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"確定",Toast.LENGTH_SHORT).show();
}
}).addCallback(new BaseTransientBottomBar.BaseCallback<Snackbar>() {
//SnakeBar顯示的時候調用
@Override
public void onShown(Snackbar transientBottomBar) {
super.onShown(transientBottomBar);
}
//SnakeBar小時的時候調用
@Override
public void onDismissed(Snackbar transientBottomBar, int event) {
super.onDismissed(transientBottomBar, event);
}
}).setActionTextColor(Color.GREEN);
((TextView)(bar.getView().findViewById(R.id.snackbar_text))).setTextColor(Color.YELLOW);
bar.show();
注意點(踩坑點):
SnakeBar在make方法中的源碼如下:
/**
* Make a Snackbar to display a message
*
* <p>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.
*
* <p>Having a {@link CoordinatorLayout} in your view hierarchy allows Snackbar to enable
* certain features, such as swipe-to-dismiss and automatically moving of widgets like
* {@link FloatingActionButton}.
*
* @param view The view to find a parent from.
* @param text The text to show. Can be formatted text.
* @param duration How long to display the message. Either {@link #LENGTH_SHORT} or {@link
* #LENGTH_LONG}
*/
@NonNull
public static Snackbar make(@NonNull View view, @NonNull CharSequence text,
@Duration int duration) {
final ViewGroup parent = findSuitableParent(view);
final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
final SnackbarContentLayout content =
(SnackbarContentLayout) inflater.inflate(
R.layout.design_layout_snackbar_include, parent, false);
final Snackbar snackbar = new Snackbar(parent, content, content);
snackbar.setText(text);
snackbar.setDuration(duration);
return snackbar;
}
其parent爲從當前的佈局文件中尋找到根佈局(爲CoordinatorLayout或FragmeLayout),所以當SnakeBar的父控件就是上述兩個佈局之一時,其顯示位置爲在父控件的底部,而並不一定在屏幕的底端,除非當其父控件的寬爲全屏時,纔會得到SnakeBar顯示在屏幕底部的效果,具體原因擼波代碼即可:
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;
}
從findSuitableParent()方法中可以看到,當前拿到的View爲CoordinatorLayout或FragmeLayout時,便結束尋找最終的父控件。