Android Snackbar控件
1. Snackbar类
Snackbar
是5.0版本出现的控件,类似于Toast
,显示在屏幕的底部,包含文字信息与一个可选的操作按钮。需要添加Design
依赖库,并且使用Theme.AppCompat
主题。
2. 创建Snackbar类
Snackbar
利用静态方法make()
来创建实例
public static Snackbar make(@NonNull View view, @StringRes int resId, @Duration int duration) {return make(view, view.getResources().getText(resId), duration);
}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;
}
创建Snackbar
实例,需要寻找合适的父视图,优先选择CoordinatorLayout
作为父视图。
private static ViewGroup findSuitableParent(View view) {ViewGroup fallback = null;do {if (view instanceof CoordinatorLayout) {// We've found a CoordinatorLayout, use itreturn (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 fallbackfallback = (ViewGroup) view;}}if (view != null) {// Else, we will loop and crawl up the view hierarchy and try to find a parentfinal 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 fallbackreturn fallback;
}
SnackbarContentLayout
继承LinearLayout
,并实现了BaseTransientBottomBar.ContentViewCallback
,包含一个TextView
和Button
。
design_layout_snackbar_include.xml
文件,
<viewxmlns:android="http://schemas.android.com/apk/res/android"class="android.support.design.internal.SnackbarContentLayout"android:theme="@style/ThemeOverlay.AppCompat.Dark"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="bottom"><TextViewandroid: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"/><Buttonandroid: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:minWidth="48dp"android:visibility="gone"android:textColor="?attr/colorAccent"style="?attr/borderlessButtonStyle"/></view>
3. Snackbar设置
Snackbar
可以设置文本和按钮
public Snackbar setText(@NonNull CharSequence message)
public Snackbar setText(@StringRes int resId)
public Snackbar setAction(@StringRes int resId, View.OnClickListener listener)
public Snackbar setAction(CharSequence text, final View.OnClickListener listener)
public Snackbar setActionTextColor(ColorStateList colors)
public Snackbar setActionTextColor(@ColorInt int color)
Snackbar
可以监听视图
addCallback(new Snackbar.Callback(){@Overridepublic void onShown(Snackbar sb) {}@Overridepublic void onDismissed(Snackbar transientBottomBar, int event) {}
})
Dismiss
的event
有下面五种情况
DISMISS_EVENT_SWIPE
,向右滑动消失,只有父视图是CoordinatorLayout
情况下才会发生DISMISS_EVENT_ACTION
,点击右侧按钮消失DISMISS_EVENT_TIMEOUT
,设置的显示时间到了消失DISMISS_EVENT_MANUAL
,调用Snackbar
的dismiss
方法消失DISMISS_EVENT_CONSECUTIVE
,新的Snackbar
出现导致旧的消失
4. SnackbarManager类
SnackbarManager
用来管理Snackbar
控件的状态。
Snackbar
的show()
方法,会调用SnackbarManager
的show(int, Callback)
方法,而mManagerCallback
会回调Snackbar
的showView()
和hideView(int)
方法。
static {sHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() {@Overridepublic boolean handleMessage(Message message) {switch (message.what) {case MSG_SHOW:((BaseTransientBottomBar) message.obj).showView();return true;case MSG_DISMISS:((BaseTransientBottomBar) message.obj).hideView(message.arg1);return true;}return false;}});
}final SnackbarManager.Callback mManagerCallback = new SnackbarManager.Callback() {@Overridepublic void show() {sHandler.sendMessage(sHandler.obtainMessage(MSG_SHOW, BaseTransientBottomBar.this));}@Overridepublic void dismiss(int event) {sHandler.sendMessage(sHandler.obtainMessage(MSG_DISMISS, event, 0,BaseTransientBottomBar.this));}
};public void show() {SnackbarManager.getInstance().show(mDuration, mManagerCallback);
}
SnackbarManager
内部包含两个记录mCurrentSnackbar
和mNextSnackbar
。在SnackbarManager
的show(int, Callback)
方法中,
- 查看是否是当前
Snackbar
,如果是,更新超时时间,结束。 - 查看是否是
NextSnackbar
,如果是,更新数据,如果不是创建新的NextSnackbar
。 - 取消当前
Snackbar
或者显示NextSnackbar
。
show(int, Callback)
方法
public void show(int duration, Callback callback) {synchronized (mLock) {if (isCurrentSnackbarLocked(callback)) {// 如果是当前Snackbar,更新duration和超时提示mCurrentSnackbar.duration = duration;mHandler.removeCallbacksAndMessages(mCurrentSnackbar);scheduleTimeoutLocked(mCurrentSnackbar);return;} else if (isNextSnackbarLocked(callback)) {// 如果是NextSnackbar,更新durationmNextSnackbar.duration = duration;} else {// 否则就创建新的NextSnackbarmNextSnackbar = new SnackbarRecord(duration, callback);}if (mCurrentSnackbar != null && cancelSnackbarLocked(mCurrentSnackbar,Snackbar.Callback.DISMISS_EVENT_CONSECUTIVE)) {// 如果当前Snackbar存在,取消显示当前Snackbar return;} else { mCurrentSnackbar = null;// 如果当前Snackbar不存在,显示NextSnackbarshowNextSnackbarLocked();}}
}// 取消显示当前Snackbar,调用callback的dismiss(DISMISS_EVENT_CONSECUTIVE)方法
private boolean cancelSnackbarLocked(SnackbarRecord record, int event) {final Callback callback = record.callback.get();if (callback != null) {// Make sure we remove any timeouts for the SnackbarRecordmHandler.removeCallbacksAndMessages(record);callback.dismiss(event);return true;}return false;
}private boolean isCurrentSnackbarLocked(Callback callback) {return mCurrentSnackbar != null && mCurrentSnackbar.isSnackbar(callback);
}private boolean isNextSnackbarLocked(Callback callback) {return mNextSnackbar != null && mNextSnackbar.isSnackbar(callback);
}// 更新超时提示
private void scheduleTimeoutLocked(SnackbarRecord r) {if (r.duration == Snackbar.LENGTH_INDEFINITE) {// If we're set to indefinite, we don't want to set a timeoutreturn;}int durationMs = LONG_DURATION_MS;if (r.duration > 0) {durationMs = r.duration;} else if (r.duration == Snackbar.LENGTH_SHORT) {durationMs = SHORT_DURATION_MS;}mHandler.removeCallbacksAndMessages(r);mHandler.sendMessageDelayed(Message.obtain(mHandler, MSG_TIMEOUT, r), durationMs);
}// 显示NextSnackbar,调用callback的show方法
private void showNextSnackbarLocked() {if (mNextSnackbar != null) {mCurrentSnackbar = mNextSnackbar;mNextSnackbar = null;final Callback callback = mCurrentSnackbar.callback.get();if (callback != null) {callback.show();} else {// The callback doesn't exist any more, clear out the SnackbarmCurrentSnackbar = null;}}
}
Snackbar
的showView()
会调用onViewShown()
,hideView(int)
会调用onViewHidden(int)
。
final void showView() {... ...if (shouldAnimate()) {// If animations are enabled, animate it inanimateViewIn();} else {// Else if anims are disabled just call back nowonViewShown();}... ...
}final void hideView(@BaseCallback.DismissEvent final int event) {if (shouldAnimate() && mView.getVisibility() == View.VISIBLE) {animateViewOut(event);} else {// If anims are disabled or the view isn't visible, just call back nowonViewHidden(event);}
}void onViewShown() {SnackbarManager.getInstance().onShown(mManagerCallback);
}void onViewHidden(int event) { SnackbarManager.getInstance().onDismissed(mManagerCallback);
}
SnackbarManager
的onShown(Callback)
和onDismissed(Callback)
方法。
public void onShown(Callback callback) {synchronized (mLock) {if (isCurrentSnackbarLocked(callback)) {scheduleTimeoutLocked(mCurrentSnackbar);}}
}public void onDismissed(Callback callback) {synchronized (mLock) {if (isCurrentSnackbarLocked(callback)) {// If the callback is from a Snackbar currently show, remove it and show a new onemCurrentSnackbar = null;if (mNextSnackbar != null) {showNextSnackbarLocked();}}}
}
Android Snackbar控件相关推荐
- android toolbar控件,Android Toolbar控件
1. Toolbar类 Toolbar是替代ActionBar的产物,低版本可以使用v7兼容包,使用Theme.AppCompat主题,并添加配置. false true 2. Toolbar配置 主 ...
- Android 开源控件与常用开发框架开发工具类
Android的加载动画AVLoadingIndicatorView 项目地址: https://github.com/81813780/AVLoadingIndicatorView 首先,在 bui ...
- 轻松上手Snackbar控件
一.前言 Snackbar 控件是 Material design 产物,它的作用是显示弹出消息,这个系统的 Toast 类似,但是它又有优于 Toast 的地方,它可以添加用户交互,如果需要,它可以 ...
- Android开源控件ViewPager Indicator的使用方法
1月16日厦门 OSC 源创会火热报名中,奖品多多哦 摘要 Android开源控件ViewPager Indicator的使用介绍 ViewPagerIndicator 目录[-] 1. V ...
- 日历控件的android代码,Android日历控件PickTime代码实例
Android日历控件PickTime代码实例 发布时间:2020-10-03 16:05:51 来源:脚本之家 阅读:86 作者:手撕高达的村长 最近做项目,需要设置用户的生日,所以做这样一个功能. ...
- android 获取控件高度_安卓开发入门教程UI控件_ImageView
什么是ImageView ImageView是用于显示图片的UI控件. 基础样例 1.展示本地图片 效果图 代码 <ImageViewandroid:layout_width="wra ...
- xamarin.android 控件,Android 库控件 - Xamarin | Microsoft Docs
Xamarin Android 库控件Xamarin.Android Gallery control 03/15/2018 本文内容 Gallery是一种布局小组件,用于显示水平滚动列表中的项,并将当 ...
- android 获取控件在屏幕中的坐标
今天,简单讲讲android如何获取控件在屏幕中的坐标. 这个其实也很简单,但是昨天做一个功能时,需要功能控件的坐标做一些逻辑操作时,居然不知道怎么做.所以在网上查找了资料后,解决了这个问题.这里记录 ...
- Android图表控件MPAndroidChart——曲线图LineChart的使用(财富收益图)
目录 前言 本文涉及文章 其他相关文章 1.数据准备 1.1 数据来源 2.曲线展示 2.1 MPAndroidChart获取 2.2 数据对象获取 2.3 数据展示 3.曲线完善 3.1 图表背景. ...
最新文章
- 判断一个序列是不是堆的方法
- 关于SQL 数据库表中的聚集索引和非聚集索引等
- Leetcode 90. 子集 II 解题思路及C++实现
- windows ternimal 使用
- tensorflow环境下的识别食物_在win10环境下进行tensorflow物体识别(ObjectDetection)训练...
- linux cd的帮助文件,linux查看命令帮助man命令详解在线手册
- Kubernetes 的自动伸缩你用对了吗?
- 设置linux环境变量
- mysql系列之4.mysql字符集
- 几岁孩子可以学python_编程python适合多大孩子学
- i5 7200u 计算机专业,i5 7200U理论性能对比_笔记本评测-中关村在线
- CIC滤波器原理及设计实现
- SQL Server 2000 打sp3补丁
- 第1章 初始JAVA
- 主题词是计算机自动提取,汉语关键词自动转换主题词方法的步骤
- 【MOS】RAC 环境中 gc block lost 和私网通信性能问题的诊断 (文档 ID 1674865.1)
- 反超苹果,微软重回全球市值第一!
- 程序化交易系统的搭建
- echarts网络拓扑图动态流程图
- 网购车平台易车与汽车之家