1

Android Snackbar简单解析

 3 years ago
source link: http://www.androidchina.net/7256.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Android Snackbar简单解析 – Android开发中文站

偶然间发现android中有Snackbar类,还是有点意思,类似于toast。与toast相比,最明显的区别是:Snackbar只能在屏幕底部显示。其他用法基本与toast相似。

先来张效果图吧,静态图:



大概的用法呢?:

Snackbar.make(btn,"Snackbar 测试",Snackbar.LENGTH_INDEFINITE).show();
//记得引入库:
compile 'com.android.support:design:xx.xx.xx'

接下来我简略翻译下部分源码:

package android.support.design.widget;
/**
* Snackbars为用户操作提供一个轻量级的反馈,
* 他在屏幕底部显示一个简略的消息,
* snackbars出现在屏幕上的所有其他要素之上,
* 同一时间只会显示一个scankbar,
* 在一定时间后他会自动消失,
* 如果传递给scankbar的父容器是CoordinatorLayout,则用户可右滑关闭他。
* Snackbars可以包含一个动作,当你调用setAction(CharSequence,      android.view.View.OnClickListener)方法时(设置一个文本,并提供一个关于该文本的点击事件。如果设置了,则文本显示在scankbar的内部右侧)
* 如果你讲关注snackbar的显示或隐藏事件,你可以设置回调函数监控addCallback(BaseCallback)
*/
public final class Snackbar extends BaseTransientBottomBar<Snackbar> {
/**
*      无限期的显示一个Snackbar。意思也就是说这个Snackbar在被调用show()后显示,直到被调用关闭,或者有另一个被显示时才会关闭。
*
*/
public static final int LENGTH_INDEFINITE = BaseTransientBottomBar.LENGTH_INDEFINITE;
public static final int LENGTH_SHORT = BaseTransientBottomBar.LENGTH_SHORT;
public static final int LENGTH_LONG = BaseTransientBottomBar.LENGTH_LONG;
/**
* Snackbar的回调类.
*
* @see BaseTransientBottomBar#addCallback(BaseCallback)
*/
public static class Callback extends BaseCallback<Snackbar> {
/** 表示Snackbar被滑动关闭.*/
public static final int DISMISS_EVENT_SWIPE = BaseCallback.DISMISS_EVENT_SWIPE;
/** 表示Snackbar被点击action后关闭.*/
public static final int DISMISS_EVENT_ACTION = BaseCallback.DISMISS_EVENT_ACTION;
/** 表示Snackbar显示到一定时间后关闭.*/
public static final int DISMISS_EVENT_TIMEOUT = BaseCallback.DISMISS_EVENT_TIMEOUT;
/** 表示Snackbar被调用dismiss()后关闭.*/
public static final int DISMISS_EVENT_MANUAL = BaseCallback.DISMISS_EVENT_MANUAL;
/** 表示Snackbar被一个新的Snackbar显示时关闭.*/
public static final int DISMISS_EVENT_CONSECUTIVE = BaseCallback.DISMISS_EVENT_CONSECUTIVE;
@Override
public void onShown(Snackbar sb) {
// Stub implementation to make API check happy.
}
@Override
public void onDismissed(Snackbar transientBottomBar, @DismissEvent int event) {
// Stub implementation to make API check happy.
}
}
private BaseCallback<Snackbar> mCallback;
private Snackbar(ViewGroup parent, View content, ContentViewCallback contentViewCallback) {
super(parent, content, contentViewCallback);
}
/**
* 构造一个对象
*
* Snackbar会尝试从给定的容器中向上寻找一个合适的父容器来托管他的view. 他的父容器会被认为是CoordinatorLayout或者是decorView.先找到了其中的某一个就结束查找。
* 如果给定的容器中包含CoordinatorLayout布局,那么这个Scankbar将会获得更多的特性,比喻滑动删除scankbar.
*
* @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);
if (parent == null) {
throw new IllegalArgumentException("No suitable parent found from the given view. "
+ "Please provide a valid 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;
}
//查找合适的父容器
private static ViewGroup findSuitableParent(View view) {
ViewGroup fallback = null;
do {
if (view instanceof CoordinatorLayout) {//如果是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;
}
/**
* 更新文本。看这意思,是可以给一个正在显示的scankbar更新文本?
*/
@NonNull
public Snackbar setText(@NonNull CharSequence message) {
final SnackbarContentLayout contentLayout = (SnackbarContentLayout) mView.getChildAt(0);
final TextView tv = contentLayout.getMessageView();
tv.setText(message);
return this;
}
/**
* 设置一个带点击动作的文本,以及回调函数。
* 点击文本的同时关闭scankbar。
* 设置了文本则显示,并设置事件。如果没有设置,则隐藏。看来是已有的布局了
* @param text     Text to display for the action
* @param listener callback to be invoked when the action is clicked
*/
@NonNull
public Snackbar setAction(CharSequence text, final View.OnClickListener listener) {
final SnackbarContentLayout contentLayout = (SnackbarContentLayout) mView.getChildAt(0);
final TextView tv = contentLayout.getActionView();
if (TextUtils.isEmpty(text) || listener == null) {
tv.setVisibility(View.GONE);
tv.setOnClickListener(null);
} else {
tv.setVisibility(View.VISIBLE);
tv.setText(text);
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onClick(view);
// Now dismiss the Snackbar
dispatchDismiss(BaseCallback.DISMISS_EVENT_ACTION);
}
});
}
return this;
}
/**
* 设置点击动作的文本颜色
*/
@NonNull
public Snackbar setActionTextColor(ColorStateList colors) {
final SnackbarContentLayout contentLayout = (SnackbarContentLayout) mView.getChildAt(0);
final TextView tv = contentLayout.getActionView();
tv.setTextColor(colors);
return this;
}
/**
* 设置回调函数,来监控scankbar的显示与隐藏动作.
* 什么?这个方法过时了?
* 请使用addCallback(BaseCallback)和removeCallback(BaseCallback)函数.
*
* @param callback Callback to notify when transient bottom bar events occur.
* @deprecated Use {@link #addCallback(BaseCallback)}
* @see Callback
* @see #addCallback(BaseCallback)
* @see #removeCallback(BaseCallback)
*/
@Deprecated
@NonNull
public Snackbar setCallback(Callback callback) {
// The logic in this method emulates what we had before support for multiple
// registered callbacks.
if (mCallback != null) {
removeCallback(mCallback);
}
if (callback != null) {
addCallback(callback);
}
// Update the deprecated field so that we can remove the passed callback the next
// time we're called
mCallback = callback;
return this;
}
...
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK