Android Material Design 系列之 Snackbar 开发详解

2,066 阅读5分钟

前言

本文是 Material Design 系列第二篇:SnackBar 的提出实际上介于 Toast 和 Dialog 的中间产物,SnackBar 提供有关操作的轻量级反馈,它们在移动设备的屏幕底部显示一条简短消息。SnackBar 出现在屏幕上所有其他元素的上方,一次只能显示一个。

它们在超时后或在屏幕上其他位置的用户交互之后自动消失,特别是在召唤新的表面或活动的交互之后。

Snackbar 与 Toast 的主要区别是:Snackbar 可以滑动退出,也可以处理用户交互(点击)事件。

一、SnackBar 特征

  • Snackbar 会在超时或者用户在屏幕其他地方触摸之后自动消失
  • 可以在屏幕上滑动关闭
  • 出现时不会阻碍用户在屏幕上的输入
  • 屏幕上同时最多只能显示一个 Snackbar
  • 可以在 Snackbar 中添加一个按钮,处理用户点击事件
  • Snackbar 一般需要 CoordinatorLayout 来作为父容器,CoordinatorLayout 保证 Snackbar 可以右滑退出

二、SnackBar 方法介绍

以下整理 SnackBar 常用的 API 方法:

方法 介绍
make(View view, CharSequence text, int duration) 创建 SnackBar 以显示消息
setAction(int resId, View.OnClickListener listener) 设置要在此显示的动作
setActionTextColor(ColorStateList colors) 设置指定操作的文本颜色
setBackgroundTint(int color) 设置背景 Drawable 的色调颜色
setCallback(Snackbar.Callback callback) 添加回调方法
show() 显示 SnackBar
dismiss() 隐藏 Snackbar
getContext() 获取父布局所使用的 Context
isShown() 判断当前 Snackbar 是否正在显示
isShownOrQueued() 判断当前 Snackbar 是否正在显示或者已经添加到队列里
setDuration(int duration) 设置消失时间
getView() Snackbar 所对应的 SnackbarBaseLayout,自定义 Sanckbar 时需要使用

三、SnackBar 使用

Snackbar 基本上继承了和 Toast 一样的方法和属性,例如 LENGTH_LONG 和 LENGTH_SHORT 用于设置显示时长。

1、基础使用

Snackbar.make(view, message, duration).show();

参数:

  • view:Snacker 要设置一个 View,Snacker 就显示在该 View 上面

  • message:Snacker 左边显示是文字内容

  • duration:Snacker 显示的时间,

    • Snackbar.LENGTH_SHORT// 短时间显示,然后自动取消
    • Snackbar.LENGTH_LONG// 长时间显示,然后自动取消
    • Snackbar.LENGTH_INDEFINITE// 不消失显示,除非手动取消
  • show():最后 Snaker 要加上这个才会显示

Snackbar.make(view, "提示:您有新消息", Snackbar.LENGTH_SHORT).show();

2、设置 SnackBar 文本颜色和背景颜色

Snackbar 的官方 API 只提供了 setActionTextColor()这个方法修改 Action 的文字颜色。在源码中我们看到 Snackbar 中定义了一个继承自 LinearLayout 的内部类 SnackbarLayout,Snackbar 的样子就是由这个 SnackbarLayout 实现的。

  • 通过 findViewById(R.id.snackbar_text)找到 SnackBar 的 id,然后强转 TextView,调用 setTextColor()方法就可以完成字体颜色设置。

  • snackbar.getView()获取到 SnackBar 背景布局 View,调用 setBackgroundColor 完成背景颜色设置。

Snackbar snackbar = Snackbar.make(view, "提示:您有新消息", Snackbar.LENGTH_SHORT);
View snackbarView = snackbar.getView();
if (snackbarView != null) {
    snackbarView.setBackgroundColor(Color.GRAY);
    ((TextView) snackbarView.findViewById(R.id.snackbar_text)).setTextColor(Color.YELLOW);
}
snackbar.show();

3、设置 setAction

setAction(CharSequence text, final OnClickListener listener)

参数:

  • text 设置 SnackBar 右侧文本
  • listener 设置右侧文本点击事件
Snackbar.make(view, "提示:您有新消息", Snackbar.LENGTH_SHORT)
      //设置Action,右边一个按钮
      .setAction("确定", click -> {
          Toast.makeText(SnackBarActivity.this,"Open Message",Toast.LENGTH_SHORT).show();
      }).show();

以上案例给 Action 设置点击事件,弹出一个 Toast,效果如下:

4、设置 setAction 文本颜色

setActionTextColor(int color)

参数:

  • color:设置文本字体颜色
Snackbar.make(view, "提示:您有新消息", Snackbar.LENGTH_SHORT)
      //设置Action,右边一个按钮
      .setAction("确定", click -> {
      })
      //设置Action文本颜色
      .setActionTextColor(Color.YELLOW)
      .show();

5、设置 SnackBar 监听事件

addCallback(BaseTransientBottomBar.BaseCallback<B> callback)

SnackBar 的回调中有个 onshow()和 onDismissed()两个重要的方法。

  • 一个是显示的时候调用
  • 一个是消失的时候调用
Snackbar.make(view, "提示:您有新消息", Snackbar.LENGTH_SHORT)
      //设置Action,右边一个按钮
      .setAction("确定", click -> {
      })
      //添加SnackBar监听事件
      .addCallback(new Snackbar.Callback() {

          @Override
          public void onShown(Snackbar sb) {
              super.onShown(sb);
              Toast.makeText(SnackBarActivity.this,"onShown",Toast.LENGTH_SHORT).show();
          }

          @Override
          public void onDismissed(Snackbar transientBottomBar, int event) {
              super.onDismissed(transientBottomBar, event);
              Toast.makeText(SnackBarActivity.this,"onDismissed",Toast.LENGTH_SHORT).show();
          }
      })
      .show();

onDismissed()方法中的 event 事件有 5 种

  1. 滑动消失的时候调用

    public static final int DISMISS_EVENT_SWIPE=0;

  2. 点击 Action 消失的时候调用

    public static final intDISMISS_EVENT_ACTION=1;

  3. 超时消失的时候调用

    public static final intDISMISS_EVENT_TIMEOUT=2;

  4. 手动调用 dismiss()方法时调用

    public static final intDISMISS_EVENT_MANUAL=3;

  5. 一个新的 SnackBar 出现的时候调用

    public static final intDISMISS_EVENT_CONSECUTIVE=4;

四、Snackbar 与 Dialog 和 Toast 的比较

Dialog

模态对话框。也就说,此刻该对话框中的内容获取了焦点,想要操作对话框以外的功能,必须先对该对话框进行响应。 应用场景:对于删除确认、版本更新等重要性提示信息,需要用户做出选择的情况下,使用 Dialog。

Toast

非模态提示框。也就说提示框的显示并不影响我们对其他地方的操作,Toast 无法手动控制隐藏,需要设置 Toast 的显示时长,一旦显示时间结束,Toast 会自动消失。如果多次点击并显示 Toast,就会出现 Toast 重复创建并显示,给用户造成一种 Toast 长时间不隐藏的幻觉。 应用场景:对于无网络提示、删除成功、发布操作完成等这类不重要的提示性信息,使用 Toast。

Snackbar

Snackbar 和 Toast 比较相似,但是用途更加广泛,并且它是可以和用户进行交互的。Snackbar 使用一个动画效果从屏幕的底部弹出来,过一段时间后也会自动消失。 应用场景:删除操作时,弹出 Snackbar 用于确认删除操作;消息发送失败时,弹出 Snackbar,用于重新发送操作;当然重要的是与 MD 组件相结合,用户体验效果更佳。

源码下载 源码包含 Material Design 系列控件集合,定时更新,敬请期待!

五、总结

SnackBar 效果比 Toast 美观的多,Material Design 系列的控件大多都是模仿 ios 的原生效果,所以现在好多项目应该都已经采用 SnackBar 来取代 Toast 了吧,本文对 SnackBar 的使用方法已经讲解的很详细了,源码中作者日常开发中整理了一个 SnackBarUtils 工具类,欢迎下载源码使用。希望看完本篇文章对你学习 SnackBar 有所帮助。

非常感谢您阅读本篇文章!
您的点赞,您的点评是对我创作最大的动力!

我的微信:Jaynm888

程序员面试交流群:764040616

诚邀 Android 程序员加入微信交流群,公众号回复加群或者加我微信邀请入群。