1
Android Snackbar简单解析
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
;
}
...
}
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK