Android Snackbar花式使用指南
发布日期:2021-11-12 07:57:03 浏览次数:23 分类:技术文章

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

原文地址:http://www.jianshu.com/p/cd1e80e64311

Snackbar是Android Support Design Library库中的一个控件,可以在屏幕底部快速弹出消息,比Toast更加好用。本文对原生Snackbar进行了修改,使其更加灵活。

1.Snackbar基本介绍

使用Snackbar要导入com.android.support:design库。

Snackbar显示在所有屏幕其它元素之上(屏幕最顶层),同一时间只能显示一个snackbar。

Snackbar的基本使用很简单,与Toast类似。

Snackbar.make(view, message_text, duration)   .setAction(action_text, click_listener)   .show();

make()方法是生成Snackbar的。Snackbar需要一个控件容器view用来容纳,官方推荐使用CoordinatorLayout来确保Snackbar和其他组件的交互,比如滑动取消Snackbar、Snackbar出现时FloatingActionButton上移。显示时间duration有三种类型LENGTH_SHORT、LENGTH_LONG和LENGTH_INDEFINITE。

setAction()方法可设置Snackbar右侧按钮,增加进行交互事件。如果不使用setAction()则只显示左侧message。

Snackbar.make(coordinatorLayout,"这是massage", Snackbar.LENGTH_LONG).setAction("这是action", new View.OnClickListener() {    @Override    public void onClick(View v) {        Toast.makeText(MainActivity.this,"你点击了action",Toast.LENGTH_SHORT).show();     } }).show();

下面这张图演示了上面代码所实现的效果:Snackbar长显示、点击Action弹出toast提示以及Snackbar在CoordinatorLayout中滑动取消。


基础演示.gif

如果你想在Snackbar的显示时或消失时做些什么,可以调用Snackbar的setCallback()方法。

2.多彩Snackbar

Snackbar和Toast的默认样式都很单一,但是有时我们希望把不同类型信息区别显示,从而使用户更容易注意到提示信息。所以使Snackbar变色是一个好主意。

Snackbar的官方API只提供了setActionTextColor()这个方法修改Action的文字颜色,这怎么办?查源码吧,哪里不会点哪里。(><)

在源码中我们看到Snackbar中定义了一个继承自LinearLayout的内部类SnackbarLayout,Snackbar的样子就是由这个SnackbarLayout实现的。

SnackbarLayout中加载了R.layout.design_layout_snackbar_include布局文件,打开后看到下面这段代码(我把padding、margin的具体数值也打了出来):

由命名可知,以snackbar_text为名的TextView就是Snackbar左侧的message。

好了,我们开始修改Snackbar的背景颜色和message字体颜色吧。

public static void setSnackbarColor(Snackbar snackbar, int messageColor, int backgroundColor) {    View view = snackbar.getView();//获取Snackbar的view    if(view!=null){        view.setBackgroundColor(backgroundColor);//修改view的背景色        ((TextView) view.findViewById(R.id.snackbar_text)).setTextColor(messageColor);//获取Snackbar的message控件,修改字体颜色    }}

很简单,没有几行代码。

本文最后提供的Snackbar封装类代码中定义了4种不同类型的信息:Info(妹子向你发来一条消息)、Confirm(妹子已收到你发出的消息)、Warning(妹子删除了你发出的消息)、Alert(妹子已将你拉黑),分别用蓝色、绿色、橙色、红色来表示。


消息信息.png

警告和错误信息演示.gif

3.在Snackbar中增加图标

短文本

通常 Snackbar 的高度应该仅仅用于容纳所有的文本,而文本应该与执行的操作相关。Snackbar 中不能包含图标,操作只能以文本的形式存在。

最多0-1个操作,不包含取消按钮

当一个动作发生的时候,应当符合提示框和可用性规则。当有2个或者2个以上的操作出现时,应该使用提示框而不是 Snackbar,即使其中的一个是取消操作。如果 Snackbar 中提示的操作重要到需要打断屏幕上正在进行的操作,那么理当使用提示框而非 Snackbar。

上面这段是谷歌 中的话。

但是我就是想在Snackbar中加图标增加趣味性,引起用户注意怎么办?我就是想在Snackbar中放两个按钮进行可选非必要操作怎么办?我就是想整幺蛾子。︿( ̄︶ ̄)︿

设计规范中的说法是有道理的,因为官方认为“Snackbar是一种针对操作的轻量级反馈机制”,做的麻烦了影响视觉感受。但是对于上述任性的开发者(或者是接了奇葩需求的苦逼开发者)我们也有解决方法。

前面我们提到过Snackbar的view是由SnackbarLayout实现的,而SnackbarLayout是继承自LinearLayout,那么我们新建一个布局添加进去不就行了么。(~o ̄ ̄)~o...

public static void SnackbarAddView(Snackbar snackbar,int layoutId,int index) {    View snackbarview = snackbar.getView();//获取snackbar的View(其实就是SnackbarLayout)    Snackbar.SnackbarLayout snackbarLayout=(Snackbar.SnackbarLayout)snackbarview;//将获取的View转换成SnackbarLayout    View add_view = LayoutInflater.from(snackbarview.getContext()).inflate(layoutId,null);//加载布局文件新建View    LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);//设置新建布局参数    p.gravity= Gravity.CENTER_VERTICAL;//设置新建布局在Snackbar内垂直居中显示    snackbarLayout.addView(add_view,index,p);//将新建布局添加进snackbarLayout相应位置}

上面的代码中,如果我们不设置向Snackbar中添加的布局文件的布局参数,新布局会显示在Snackbar内的顶部。使用上述任性方法的时候要注意新加布局的大小和Snackbar内文字长度,Snackbar过大或过于花哨了可不好看。

下面是使用示例。我们先新建一个布局,暂时命名为snackbar_addview.xml,简单的放进了一个ImageView,图片就是android默认图标。

然后在activity中写下snackbar的设置:

Snackbar snackbar= Snackbar.make(coordinatorLayout,"这是massage", Snackbar.LENGTH_LONG); SnackbarUtil.setSnackbarColor(snackbar,SnackbarUtil.blue); SnackbarUtil.SnackbarAddView(snackbar,R.layout.snackbar_addview,0);  snackbar.show();

添加图标演示.gif

4.SnackbarUtil

我将我常用的Snackbar相关设置封装成了一个类,大家可以根据自己的需求使用。

/** * Created by 赵晨璞 on 2016/5/1. */public class SnackbarUtil {public static final   int Info = 1;public static final  int Confirm = 2;public static final  int Warning = 3;public static final  int Alert = 4;public static  int red = 0xfff44336;public static  int green = 0xff4caf50;public static  int blue = 0xff2195f3;public static  int orange = 0xffffc107;/** * 短显示Snackbar,自定义颜色 * @param view * @param message * @param messageColor * @param backgroundColor * @return */public static Snackbar ShortSnackbar(View view, String message, int messageColor, int backgroundColor){    Snackbar snackbar = Snackbar.make(view,message, Snackbar.LENGTH_SHORT);    setSnackbarColor(snackbar,messageColor,backgroundColor);    return snackbar;}/** * 长显示Snackbar,自定义颜色 * @param view * @param message * @param messageColor * @param backgroundColor * @return */public static Snackbar LongSnackbar(View view, String message, int messageColor, int backgroundColor){    Snackbar snackbar = Snackbar.make(view,message, Snackbar.LENGTH_LONG);    setSnackbarColor(snackbar,messageColor,backgroundColor);    return snackbar;}/** * 自定义时常显示Snackbar,自定义颜色 * @param view * @param message * @param messageColor * @param backgroundColor * @return */public static Snackbar IndefiniteSnackbar(View view, String message,int duration,int messageColor, int backgroundColor){    Snackbar snackbar = Snackbar.make(view,message, Snackbar.LENGTH_INDEFINITE).setDuration(duration);    setSnackbarColor(snackbar,messageColor,backgroundColor);    return snackbar;}/** * 短显示Snackbar,可选预设类型 * @param view * @param message * @param type * @return */public static Snackbar ShortSnackbar(View view, String message, int type){    Snackbar snackbar = Snackbar.make(view,message, Snackbar.LENGTH_SHORT);    switchType(snackbar,type);    return snackbar;}/** * 长显示Snackbar,可选预设类型 * @param view * @param message * @param type * @return */public static Snackbar LongSnackbar(View view, String message,int type){    Snackbar snackbar = Snackbar.make(view,message, Snackbar.LENGTH_LONG);    switchType(snackbar,type);    return snackbar;}/** * 自定义时常显示Snackbar,可选预设类型 * @param view * @param message * @param type * @return */public static Snackbar IndefiniteSnackbar(View view, String message,int duration,int type){    Snackbar snackbar = Snackbar.make(view,message, Snackbar.LENGTH_INDEFINITE).setDuration(duration);    switchType(snackbar,type);    return snackbar;}//选择预设类型private static void switchType(Snackbar snackbar,int type){    switch (type){        case Info:            setSnackbarColor(snackbar,blue);            break;        case Confirm:            setSnackbarColor(snackbar,green);            break;        case Warning:            setSnackbarColor(snackbar,orange);            break;        case Alert:            setSnackbarColor(snackbar,Color.YELLOW,red);            break;    }}/** * 设置Snackbar背景颜色 * @param snackbar * @param backgroundColor */public static void setSnackbarColor(Snackbar snackbar, int backgroundColor) {    View view = snackbar.getView();    if(view!=null){        view.setBackgroundColor(backgroundColor);    }}/** * 设置Snackbar文字和背景颜色 * @param snackbar * @param messageColor * @param backgroundColor */public static void setSnackbarColor(Snackbar snackbar, int messageColor, int backgroundColor) {    View view = snackbar.getView();    if(view!=null){        view.setBackgroundColor(backgroundColor);        ((TextView) view.findViewById(R.id.snackbar_text)).setTextColor(messageColor);    }}/** * 向Snackbar中添加view * @param snackbar * @param layoutId * @param index 新加布局在Snackbar中的位置 */public static void SnackbarAddView( Snackbar snackbar,int layoutId,int index) {    View snackbarview = snackbar.getView();    Snackbar.SnackbarLayout snackbarLayout=(Snackbar.SnackbarLayout)snackbarview;    View add_view = LayoutInflater.from(snackbarview.getContext()).inflate(layoutId,null);    LinearLayout.LayoutParams p = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);    p.gravity= Gravity.CENTER_VERTICAL;    snackbarLayout.addView(add_view,index,p);}}

简单的使用示例:

SnackbarUtil.ShortSnackbar(coordinator,"妹子向你发来一条消息",SnackbarUtil.Info).show();

消息演示.gif

整出幺蛾子的使用示例:

Snackbar snackbar= SnackbarUtil.ShortSnackbar(coordinator,"妹子删了你发出的消息",SnackbarUtil.Warning).setActionTextColor(Color.RED).setAction("再次发送", new View.OnClickListener() {    @Override     public void onClick(View v) {        SnackbarUtil.LongSnackbar(coordinator,"妹子已将你拉黑",SnackbarUtil.Alert).setActionTextColor(Color.WHITE).show();    } }); SnackbarUtil.SnackbarAddView(snackbar,R.layout.snackbar_addview,0); SnackbarUtil.SnackbarAddView(snackbar,R.layout.snackbar_addview2,2);  snackbar.show();

这个示例中调用了两次SnackbarAddView()方法向Snackbar中添加了两个不同的自定义布局,效果如下(不建议大家这么玩 _(:з」∠)_ ):


添加多布局.gif

暂时就是这些。[]~( ̄ ̄)~*

转载地址:https://blog.csdn.net/happy_love1990/article/details/67103134 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Android实时监听网络状态
下一篇:Android Toast自定义使用

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年04月01日 12时27分45秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

剑指 Offer 26. 树的子结构 - leetcode 剑指offer系列 2019-04-26
剑指 Offer 27. 二叉树的镜像 - leetcode 剑指offer系列 2019-04-26
剑指 Offer 28. 对称的二叉树 - leetcode 剑指offer系列 2019-04-26
剑指 Offer 29. 顺时针打印矩阵 - leetcode 剑指offer系列 2019-04-26
剑指 Offer 30. 包含min函数的栈 - leetcode 剑指offer系列 2019-04-26
剑指 Offer 31. 栈的压入、弹出序列 - leetcode 剑指offer系列 2019-04-26
剑指 Offer 32 - I. 从上到下打印二叉树 - leetcode 剑指offer系列 2019-04-26
剑指 Offer 32 - II. 从上到下打印二叉树 II - leetcode 剑指offer系列 2019-04-26
剑指 Offer 32 - III. 从上到下打印二叉树 III - leetcode 剑指offer系列 2019-04-26
剑指 Offer 33. 二叉搜索树的后序遍历序列 - leetcode 剑指offer系列 2019-04-26
剑指 Offer 34. 二叉树中和为某一值的路径 - leetcode 剑指offer系列 2019-04-26
面试官上来就问:Java 进程中有哪些组件会占用内存? 2019-04-26
VMWare虚拟机下Fedora30升级Fedora31,重启后无法启动系统,出现alloc magic is broken at 0xXXXX的错误 2019-04-26
【解决方案】STM32L152单片机驱动段码LCD屏,执行HAL_LCD_Init函数失败返回HAL_TIMEOUT,长时间卡在LCD_FLAG_RDY的while循环里面的解决办法 2019-04-26
【方法】STM32F103C8单片机在Keil 5环境下使用C++编写程序,并将printf和cout重定向到串口 2019-04-26
【STemWin】STM32F429IG单片机用LTDC驱动正点原子7寸RGB彩色触摸屏,并裸机移植STemWin图形库 2019-04-26
【经验分享】调试STM32F107VC单片机驱动DP83848以太网PHY芯片时遇到的问题 2019-04-26
【程序】STM32F107VC单片机驱动DP83848以太网PHY芯片,移植lwip 2.1.2协议栈,并加入网线热插拔检测的功能(HAL库) 2019-04-26
【BUG处理】STM32F1和F2单片机上用HAL库的USART串口接收函数HAL_UART_Receive_IT循环接收串口字符,串口接收大批量数据后突然死机,不能继续接收的解决办法 2019-04-26
在PCB板上调试104(0.1μF)独石电容驱动MAXIM MAX3232串口芯片的心得 2019-04-26