Android中Snackbar的使用方法及小技巧

前言

Snackbar和Toast相似,都是为了给用户提供交互信息,Snackbar是固定在底部的,显示时从下往上滑出

要使用Snackbar,需要在项目的build.gradle中添加依赖

dependencies {
 compile 'com.android.support:design:23.4.0'
}

Snackbar的使用方法和Toast很相似

Snackbar.make(mOpenTv, "消息内容", Snackbar.LENGTH_SHORT)
  .setAction("确定", new View.OnClickListener() {
  @Override
  public void onClick(View v) {
  }
  })
  .show();

第一个参数需要传入一个View,可以是界面当中的任意一个View控件,Snackbar会自动根据这个控件找到最外层的布局来显示

第二个参数就是我们需要显示的内容,注意这里的内容最多显示两行哦,超出两行后的内容会变成“…”

第三个参数为Snackbar显示的时长,有三种模式供选择

  • LENGTH_SHORT:短时间显示
  • LENGTH_LONG:长时间显示
  • LENGTH_INDEFINITE:一直显示,只有当用户触发Action点击事件或手动删除时才会消失

Snackbar可以通过setAction方法设置一个点击事件,和用户进行交互

我们还可以通过setCallback方法来监听Snackbar的显示和关闭

 Snackbar sb = Snackbar.make(mOpenTv, "消息内容", Snackbar.LENGTH_SHORT);
 sb.setCallback(new Snackbar.Callback() {
 @Override
 public void onDismissed(Snackbar snackbar, int event) {
 super.onDismissed(snackbar, event);
 // Snackbar关闭时回调
 }

 @Override
 public void onShown(Snackbar snackbar) {
 super.onShown(snackbar);
 // Snackbar打开时回调
 }
 });
 sb.show();

Snackbar还支持滑出删除,需要在布局文件中使用CoordinatorLayout作为根布局

建议要使用Snackbar的时候最好是以CoordinatorLayout作为根布局,如果以其它RelativeLayout,LinearLayout等作为根布局的话,会出现以下这种情况

FloatingActionButton被遮到了,使用CoordinatorLayout作为根布局可以避免这种情况

Snackbar只能在底部显示吗?

是也不是,为啥这么说呢,Snackbar确实是在CoordinatorLayout底部显示的,但并不等于是在屏幕顶部

首先我们要知道Snackbar显示的原理是什么

之前介绍中的第一个传进去的参数View,Snackbar会通过这个View控件找到它所在的根布局,我们来查看下源码

 public static Snackbar make(@NonNull View view, @NonNull CharSequence text,
  @Duration int duration) {
 Snackbar snackbar = new Snackbar(findSuitableParent(view));
 snackbar.setText(text);
 snackbar.setDuration(duration);
 return snackbar;
 }

我们传进去的view会经过findSuitableParent方法的处理,我们再来看下这个方法的具体实现

 private static ViewGroup findSuitableParent(View view) {
 ViewGroup fallback = null;
 do {
  if (view instanceof 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;
 }

详细的过程google的工程师已经写的非常的清楚了,我们主要需要了解的就是当一个View的直接父布局为CoordinatorLayout时,就以这个CoordinatorLayout为标准来显示Snackbar

我们可以做个小实验验证一下

在传入的View控件外面套一层CoordinatorLayout

 <android.support.design.widget.CoordinatorLayout
 android:layout_width="match_parent"
 android:layout_height="100dp">

 <TextView
  android:id="@+id/tv_open_snackbar"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:gravity="center"
  android:text="打开Snackbar"
  android:textSize="28sp"/>
 </android.support.design.widget.CoordinatorLayout>

再运行一下看看,效果就变成了下面这样

所以说Snackbar的显示位置还是可以通过这个小技巧来改变的

如果嫌默认的Snackbar太丑怎么办?

我们可以来自定义它的外观

1.改变按钮的文字颜色

通过调用setActionTextColor方法即可改变按钮的文字颜色

 Snackbar sb = Snackbar.make(mOpenTv, "消息内容", Snackbar.LENGTH_SHORT);
 sb.setAction("确定", new View.OnClickListener() {
  @Override
  public void onClick(View v) {
  }
 });
 sb.setActionTextColor(Color.YELLOW);
 sb.show();

2.改变消息内容的文字颜色

Snackbar没有给我们提供改变消息文本颜色的api接口,但在查看源码时发现了这个方法getView

 /**
 * Returns the {@link Snackbar}'s view.
 */
 @NonNull
 public View getView() {
 return mView;
 }

这里返回的mView其实是一个SnackbarLayout布局,在SnackbarLayout的构造方法中找到了它的布局文件design_layout_snackbar_include

  // Now inflate our content. We need to do this manually rather than using an <include>
  // in the layout since older versions of the Android do not inflate includes with
  // the correct Context.
  LayoutInflater.from(context).inflate(R.layout.design_layout_snackbar_include, this);

design_layout_snackbar_include布局文件里只有两个控件,一个TextView,一个Button

<merge xmlns:android="http://schemas.android.com/apk/res/android">

 <TextView
  android: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"/>

 <Button
  android: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: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:visibility="gone"
  android:textColor="?attr/colorAccent"
  style="?attr/borderlessButtonStyle"/>
</merge>

相信看到这里大家应该知道怎么做了,TextView的id为snackbar_text,我们通过getView()来获取这个TextView控件

 Snackbar sb = Snackbar.make(mOpenTv, "消息内容", Snackbar.LENGTH_SHORT);
 sb.setAction("确定", new View.OnClickListener() {
  @Override
  public void onClick(View v) {
  }
 });
 sb.setActionTextColor(Color.YELLOW);
 View view = sb.getView();
 TextView tv = (TextView) view.findViewById(R.id.snackbar_text);
 tv.setTextColor(Color.RED);
 sb.show();

同样的,我们也可以通过tv.setTextSize设置它的文字大小

3.改变消息内容的背景

同理,根据以上方法,得到它的布局,调用对应的api接口就好

  View view = sb.getView();
  view.setBackgroundColor(Color.RED);

像这种红红的给用户警告的提示,是不是比Toast要来的炫酷多了呢

4.给消息内容添加图标

获取到消息内容的TextView后,调用setCompoundDrawables方法设置它的图标,可自由选择图标放置的位置,四个参数分别对应TextView的左、上、右、下

  Snackbar sb = Snackbar.make(mOpenTv, "消息内容", Snackbar.LENGTH_SHORT);
  sb.setAction("确定", new View.OnClickListener() {
   @Override
   public void onClick(View v) {
   }
  });
  sb.setActionTextColor(Color.YELLOW);
  View view = sb.getView();
  TextView tv = (TextView) view.findViewById(R.id.snackbar_text);
  Drawable d = ContextCompat.getDrawable(this, R.drawable.warn);
  d.setBounds(0, 0, d.getMinimumWidth(), d.getMinimumHeight());
  tv.setCompoundDrawables(d, null, null, null); // 给TextView左边添加图标
  tv.setGravity(Gravity.CENTER); // 让文字居中
  sb.show();
 }

注意要设置setGravity使其居中,不然文字默认在上面不好看啊

就先介绍这么多,其实只要拿到了它的布局,接下来怎么整就看各位的喜好啦

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • Android 开发之Dialog,Toast,Snackbar提醒

    今天给大家带来一篇简单易懂的微技巧文章,并没有什么高深的技术点,但重点是在细节,相信可以给不少朋友带来帮助. Dialog和Toast所有人肯定都不会陌生的,这个我们平时用的实在是太多了.而Snackbar是Design Support库中提供的新控件,有些朋友可能已经用过了,有些朋友可能还没去了解.但是你真的知道什么时候应该使用Dialog,什么时候应该使用Toast,什么时候应该使用Snackbar吗?先看效果图: 1,Dialog 首先来介绍一下Dialog的用法: AlertDialog

  • Android中如何指定SnackBar在屏幕的位置及小问题解决

    Android指定SnackBar在屏幕的位置 Snackbar 常以一个小的弹出框的形式,出现在手机屏幕下方或者桌面左下方,并且是在屏幕所有层的最上方.如果要指定它在屏幕出现的位置,可以把SnackBar放置在android.support.design.widget.CoordinatorLayout内. 在RelativeLayout里添加CoordinatorLayout如下: <android.support.design.widget.CoordinatorLayout androi

  • Android重要控件SnackBar使用方法详解

    SnackBar是DesignSupportLibrary中的一个重要的控件,用于在界面下面提示一些关键信息,跟Toast不同的地方是SnackBar允许用户向右滑动消除它,同时,也允许在SnackBar中设定一个Action,当用户点击了SnackBar里面的按钮的时候,可以进行一些操作,所以,功能绝对是很强大的. SnackBar的构造: // 参数分别是父容器,提示信息,持续时间public static Snackbar make(@NonNull View view, @NonNull

  • Android提醒微技巧你真的了解Dialog、Toast和Snackbar吗

    Dialog和Toast所有人肯定都不会陌生的,这个我们平时用的实在是太多了.而Snackbar是Design Support库中提供的新控件,有些朋友可能已经用过了,有些朋友可能还没去了解.但是你真的知道什么时候应该使用Dialog,什么时候应该使用Toast,什么时候应该使用Snackbar吗?本篇文章中我们就来学习一下这三者使用的时机,另外还会介绍一些额外的技巧. 1. Dialog 首先来介绍一下Dialog的用法吧,其实很简单,相信大多数人都是经常使用的: AlertDialog.Bu

  • Android中Snackbar的使用方法及小技巧

    前言 Snackbar和Toast相似,都是为了给用户提供交互信息,Snackbar是固定在底部的,显示时从下往上滑出 要使用Snackbar,需要在项目的build.gradle中添加依赖 dependencies { compile 'com.android.support:design:23.4.0' } Snackbar的使用方法和Toast很相似 Snackbar.make(mOpenTv, "消息内容", Snackbar.LENGTH_SHORT) .setAction(

  • Android中XUtils3框架使用方法详解(一)

    xUtils简介 xUtils 包含了很多实用的android工具. xUtils 支持大文件上传,更全面的http请求协议支持(10种谓词),拥有更加灵活的ORM,更多的事件注解支持且不受混淆影响... xUitls 最低兼容android 2.2 (api level 8) 今天给大家带来XUtils3的基本介绍,本文章的案例都是基于XUtils3的API语法进行的演示.相信大家对这个框架也都了解过, 下面简单介绍下XUtils3的一些基本知识. XUtils3一共有4大功能:注解模块,网络

  • android中圆角图像生成方法

    本文实例讲述了android中圆角图像生成方法.分享给大家供大家参考.具体分析如下: 在android开发中为了美观,常常要求ImageView中显示出圆角图像的效果,这个如何实现? 这里总结了网上的最优方法:将图像处理成圆角,然后在加载给ImageView显示,代码如下: public Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) { Bitmap output = Bitmap.createBitmap(bitmap.get

  • Android中闪屏实现方法小结(普通闪屏、倒计时闪屏、倒计时+动画闪屏)

    一.项目目录结构 二.activity_main.xml代码 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match

  • Android中Blade的使用方法

    启动Activity并传递参数 Extra 正常情况下启动Activity并且传递参数的代码: Intent intent = new Intent(context,LoginActivity.class); intent.putExtra("phone","123456); intent.putExtra("pwd","123456); startActivity(intent); 使用Blade启动Activity的方式 public cla

  • 详解Android中Intent的使用方法

    一.Intent的用途 Intent主要有以下几种重要用途: 1. 启动Activity:可以将Intent对象传递给startActivity()方法或startActivityForResult()方法以启动一个Activity,该Intent对象包含了要启动的Activity的信息及其他必要的数据. 2. 启动Service:可以将Intent对象传递给startService()方法或bindService()方法以启动一个Service,该Intent对象包含了要启动的Service的

  • Android中bindService基本使用方法概述

    Android中有两种主要方式使用Service,通过调用Context的startService方法或调用Context的bindService方法,本文只探讨纯bindService的使用,不涉及任何startService方法调用的情况.如果想了解startService相关的使用,请参见<Android中startService基本使用方法概述>. bindService启动服务的特点 相比于用startService启动的Service,bindService启动的服务具有如下特点:

  • Android 中RxPermissions 的使用方法详解

    Android 中RxPermissions 的使用方法详解 以请求拍照.读取位置权限为例 module的build.gradle: compile 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar' compile 'io.reactivex.rxjava2:rxjava:2.0.5' AndroidManifest.xml: <uses-permission android:name="android.permission.AC

  • Android 中Context的使用方法详解

    Android 中Context的使用方法详解 概要: Context字面意思是上下文,位于framework package的android.content.Context中,其实该类为LONG型,类似Win32中的Handle句柄.很多方法需要通过 Context才能识别调用者的实例:比如说Toast的第一个参数就是Context,一般在Activity中我们直接用this代替,代表调用者的实例为Activity,而到了一个button的onClick(View view)等方法时,我们用t

  • Android中imageview.ScaleType使用方法详细介绍

    Android中imageview.ScaleType使用方法详细介绍 ScaleType属性用以表示显示图片的方式,共有8种取值: ScaleType.CENTER:图片大小为原始大小,如果图片大小大于ImageView控件,则截取图片中间部分,若小于,则直接将图片居中显示. ScaleType.CENTER_CROP:将图片等比例缩放,让图像的短边与ImageView的边长度相同,即不能留有空白,缩放后截取中间部分进行显示. ScaleType.CENTER_INSIDE:将图片大小大于Im

随机推荐