博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android Material Design 系列之 SnackBar详解
阅读量:5328 次
发布时间:2019-06-14

本文共 4077 字,大约阅读时间需要 13 分钟。

SnackBar是google Material Design提供的一种轻量级反馈组件。支持从布局的底部显示一个简洁的提示信息,支持手动滑动取消操作,同时在同一个时间内只能显示一个SnackBar.

 

Snackbar是如何实现的呢?我们主要讨论Snackbar的显示逻辑,包括:延迟消失和同一时间只支持一个Snackbar显示

首先我们先看下Snackbar用到的两个类

其中SnackbarManager是个单例,利用单例的形式来保证每次只会显示一个Snackbar。

 

Snackbar中的sHandler用于SnackbarManager.Callback回调函数中,每个Snackbar都会去实现SnackbarManager.Callback的回调,包括show和dimiss两个方法。SnackbarManager也是通过这个回调来区分每个不同的Snackbar

private boolean isCurrentSnackbarLocked(ConvinentSnackbarManager.Callback callback) {    return mCurrentSnackbar != null && mCurrentSnackbar.isSnackbar(callback);}

  

为了方便用户能够对Snackbar的行为进行自定义操作,Snackbar提供了 Snackbar.Callback,包括了Snackbar显示,消失后的行为。用户可以根据自己的业务需求,设置这个callback.具体提供的接口方法如下:

/**         * Called when the given {@link ConvinentSnackbar} has been dismissed, either through a time-out,         * having been manually dismissed, or an action being clicked.         *         * @param snackbar The snackbar which has been dismissed.         * @param event    The event which caused the dismissal. One of either:         *                 {@link #DISMISS_EVENT_SWIPE}, {@link #DISMISS_EVENT_ACTION},         *                 {@link #DISMISS_EVENT_TIMEOUT}, {@link #DISMISS_EVENT_MANUAL} or         *                 {@link #DISMISS_EVENT_CONSECUTIVE}.         * @see ConvinentSnackbar#dismiss()         */        public void onDismissed(ConvinentSnackbar snackbar, @ConvinentSnackbar.Callback.DismissEvent int event) {            // empty        }        /**         * Called when the given {@link ConvinentSnackbar} is visible.         *         * @param snackbar The snackbar which is now visible.         * @see ConvinentSnackbar#show()         */        public void onShown(ConvinentSnackbar snackbar) {            // empty        }

  

SnackbarManager中,为了保存每个一个Snackbar,提供了SnackBarRecord的内部类,这个类有两个成员变量,一个是Snackbar的callback,一个是这个Snackbar的duration。但是SnackBarManager不是用一个队列去保存每一个新生成的不同的Snackbar。只会保存当前和一下要显示的。而下一个的规则是:在一个Snackbar的显示周期中(已经有一个Snackbar存在的情况下),只会把最后一个新的Snackbar作为下一个Snackbar。假如你每点击一次按钮都会新生成一个Snackbar,那么在2.75s(LONG_DURATION_MS)内,你点击了N次,SnackBarManager只会显示1次和第N次。其它的都不会显示。并且第N次的显示是在第一次显示结束后会自动调用显示

public void show(int duration, ConvinentSnackbarManager.Callback callback) {        synchronized (mLock) {            if (isCurrentSnackbarLocked(callback)) {                // Means that the callback is already in the queue. We'll just update the duration                mCurrentSnackbar.duration = duration;                // If this is the ConvinentSnackbar currently being shown, call re-schedule it's                // timeout                mHandler.removeCallbacksAndMessages(mCurrentSnackbar);                scheduleTimeoutLocked(mCurrentSnackbar);                return;            } else if (isNextSnackbarLocked(callback)) {                // We'll just update the duration                mNextSnackbar.duration = duration;            } else {                // Else, we need to create a new record and queue it                mNextSnackbar = new ConvinentSnackbarManager.SnackbarRecord(duration, callback);            }            if (mCurrentSnackbar != null && cancelSnackbarLocked(mCurrentSnackbar,                    ConvinentSnackbar.Callback.DISMISS_EVENT_CONSECUTIVE)) {                // If we currently have a ConvinentSnackbar, try and cancel it and wait in line                return;            } else {                // Clear out the current snackbar                mCurrentSnackbar = null;                // Otherwise, just show it now                showNextSnackbarLocked();            }        }    }

  

SnackbarManager里也有一个Handler,这个Handler是用于延迟消失动画的。每次生成一个SnackBar,如果duration不是设置为LENGTH_INDEFINITE(不消失),SnackbarManager在显示之后,都会用这个Handler的sendMessageDelayed

 来进行延迟发送一个消失消息。Handler在收到这个消息后,会调用SnackbarManager.Callback 

,通过SnackbarManager的Callback来实现Snackbar的显示和消失。

 

Snackbar的优点:

 提供了比Toast更灵活和更友好的显示方法。

 

Snackbar的优点:

1.显示位置过于单一,现在目前只支持底部显示。

2.滑动操作过于单一,现在只支持从左向右滑动取消。

 

对Snackbar进行了些改动,github的项目为ConvinentSnackbar。地址为:

https://github.com/stephen-wu-yuan/ConvinentSnackbar

改组件支持设置滑动方向和支持顶部显示。

 

 

 

 

 

 

转载于:https://www.cnblogs.com/StephenWu/p/6217234.html

你可能感兴趣的文章
SSM+Jedis初体验
查看>>
JAVA共通関数--シングルクォーテーションをSQL用に追加する
查看>>
暑假第十一测
查看>>
POJ - 2891 中国剩余定理
查看>>
Tyvj - 1305 单调队列优化dp
查看>>
18华工校赛 小马哥的超级盐水 折半枚举
查看>>
挂钩SSDT详解附源代码
查看>>
iDoubs的编译问题以及解决方案
查看>>
[USACO07DEC]道路建设Building Roads
查看>>
Jmeter登录接口返回 status415
查看>>
iOS动画和第三方插件学习网址
查看>>
C/C++ 格式化读取和读取一行
查看>>
PHP正则表达式完全手册
查看>>
POJ 3268 Silver Cow Party
查看>>
内存和cpu
查看>>
js中Array自定义contains, indexOf, delete方法.
查看>>
重命名流程
查看>>
array 删除指定的元素的方法
查看>>
汇编语言相关图书推荐
查看>>
CBMVC For Titanium Alloy 发布!
查看>>