Android中Snackbar的使用方法及小技巧
作者:ZHU_文涛 发布时间:2023-10-30 03:13:31
前言
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使其居中,不然文字默认在上面不好看啊
就先介绍这么多,其实只要拿到了它的布局,接下来怎么整就看各位的喜好啦
来源:https://blog.csdn.net/zhuwentao2150/article/details/52304202


猜你喜欢
- 启动类的存放位置今天,写了一个项目,但是启动类为什么一直报错我是放在这个位置的,但是就一直报放在默认包错误 想记录下微服务启动类的
- 目录:DioManager:Dio辅助类NWMethod:请求方法,get、post等NWApi:大家都知道EntityFactory:js
- 本文实例讲述了Android开发之绘制平面上的多边形功能。分享给大家供大家参考,具体如下:计算机里的3D图形其实是由很多个平面组合而成的。所
- 一:将String字符串放在最前面防止发生NullPointerException异常,我们通常把String字符串放在equals方法的左
- 一、概述UDP和TCP是网络通讯常用的两个传输协议,C#一般可以通过Socket来实现UDP和TCP通讯,由于.NET框架通过UdpClie
- 背景:在平时的开发中,我们时常会遇到下列场景公司的组织架构的数据存储与展示文件夹层级的数据存储与展示评论系统中,父评论与诸多子评论的数据存储
- 本项目主要实现对汽车维修厂的信息化管理功能,主要包含三个角色:管理员,维修师傅,客户。实现的主要功能包含用户管理、配置管理、汽车管理、故障管
- 业务背景电商订单项目分正向和逆向两个部分:其中正向数据库记录了订单的基本信息,包括订单基本信息、订单商品信息、优惠卷信息、发票信息、账期信息
- 这篇文章主要介绍了Java内存缓存工具Guava LoadingCache使用解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有
- 什么是Spring BootSpring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初
- Struts2中提供了数据校验验证数据例如验证邮件、数字等。验证方式有3种:一是通过validate()方法,二是通过Xml,三是使用注解方
- 目录wait-notifyjoin方式ReentrantLockReentrantLock+ConditionSemaphore三个线程T1
- final,static,this,super 关键字总结正文开始@Assassin1. final 关键字:final 关键字,意思是最终
- 一、概述一个Process组件提供了在计算机运行进程的访问权限。 进程,在最简单的术语中,是正在运行的应用。提供对本地和远程进程的访问权限并
- 前面的文章介绍了如何进行权限控制,即访问控制器或者方法的时候,要求当前用户必须具备特定的权限,但是如何在程序中进行权限的分配呢?下面就介绍下
- 【背景】spring-boot项目,打包成可执行jar,项目内有两个带有main方法的类并且都使用了@SpringBootApplicati
- 这篇文章主要介绍了MyBatis Mapper接受参数的四种方式代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考
- 在java中读取读取文件,经常因为路径的问题找不到,此文用于记录如何定位文件的简单方法。本基于springboot做的测试,主要是构建工程方
- 用java实现循环队列的方法:1、添加一个属性size用来记录眼下的元素个数。目的是当head=rear的时候。通过size=0还是size
- 如果对空的对象进行操作,就会造成意外错误。所以我们在使用对象前,一般会进行非空判断接下来介绍我知道的三种判断非空方法:1、if判断这个最直接