安卓高级6 SnackBar

引言

文/李牧羊(简书作者)
原文链接:http://www.jianshu.com/p/2654e6bda3b1
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

在之前我有提到这一篇Android Design Support Library系列文章是关于SnackBar的,但是由于要用到CoordinatorLayout所以先翻译了一篇相关文章,如果还不了解的可以先看一下Android Design Support Library--使用CoordinatorLayout来处理滚动 ,这一篇我们讲SnackBar,SnackBar其实就是Toast的升级版,他们之间最大的不同就是:SnackBar会对我们的操作提供一个轻量级的反馈,并且可以对点击事件做出响应,如果是在手机上使用一个SnackBar的话,我们会看到在屏幕底部出现一条简短的信息,如果是在更大的屏幕上这条信息应该会显示在左下角,并且当一个SnackBar显示的时候它是凌驾于当前所有屏幕元素之上的,我们在屏幕上一次只能显示一个SnackBar,如果这么讲不是很清楚的话,我们先来看一个小Demo,通过代码驱动理解是比较好的方式。

示例

根据SnackBar的特点,在屏幕上显示出不同的SnackBar,效果如下:


这里写图片描述

先看一下相关的API文档:

方法类型方法作用
voiddismiss()使SnackBar消失
intgetDuration()返回SnackBar的持续时间
ViewgetView()返回当前SnackBar的View
booleanisShown()判断该SnackBar是否正在显示
booleanisShownOrQueued()判断该SnackBar是否正在显示或者排队等待即将要显示
static Snackbarmake(View view, int resId, int duration)新建一个用来显示信息的SnackBar
static Snackbarmake(View view, CharSequence text, int duration)同上
SnackbarsetAction(int resId, View.OnClickListener listener)设置这个即将显示的SnackBar的动作
SnackbarsetAction(CharSequence text, View.OnClickListener listener)同上
SnackbarsetActionTextColor(ColorStateList colors)设置action的文字颜色(右边的)
SnackbarsetActionTextColor(int color)同上
SnackbarsetCallback(Snackbar.Callback callback)设置一个回调,当SnackBar的可见性改变的时候调用
SnackbarsetDuration(int duration)设置SnackBar信息的显示时间
SnackbarsetText(int resId)更新SnackBar上显示的文字
SnackbarsetText(CharSequence message)同上
voidshow()显示SnackBar,最后一定要调用这个方法,不然SnackBar不显示,联想Toast

可以看到Demo上显示了三种不同的SnackBar,我们都知道SnackBar是Toast的升级版,但也说明了一个问题那就是SnackBar是用来显示消息的,同时根据你的需求不同可以对这些消息做出一定的响应动作,下面分析三种显示消息方式的不同: - 普通的SnackBar也许有的人并没有过多的需求,只是单纯地想把SnackBar当作一个显示消息的控件而已,那么可以很简单的在代码中这么使用:

Snackbar.make(mCoor, R.string.normal, Snackbar.LENGTH_SHORT).show();

对比一下我们的Toast方式:

Toast.makeText(MainActivity.this,R.string.normal,Toast.LENGTH_SHORT).show();

是不是很像,没错简单的使用的话SnackBar跟Toast并没有多大区别,但是动画效果上是有差异的,如果你注意到了这一点:


这里写图片描述


看,这个侧边滑动消失的效果只有当你使用CoordinatorLayout作为根布局才有,这就是为什么在写SnackBar之前我要先说明一下CoordinatorLayout的原因,如果你使用普通的LinearLayout或者RelativeLayout是不会有这种动画交互效果的,另外,注意SnackBar的make方法有两种重载方法,分别是:

make(View view, int resId, int duration)

make(View view, CharSequence text, int duration)

这里有三个参数,第一个参数View表示的意思是我们传入一个View,然后SnackBar会遍历整个View Tree来找到一个合适的View承载SnackBar的View,如果你想要实现上面的动画交互效果的话最好是传入CoordinatorLayout对象,第二个参数的话是两个重载方法不同的地方,有一种是我们熟知的:

Snackbar.make(mCoor, "普通的SnackBar", Snackbar.LENGTH_SHORT).show();

还有一种要求传入一个ID,注意这个ID并不是指其他的什么,就是你在string.xml文件中定义的字符串资源的ID,比如这样:

Snackbar.make(mCoor, R.string.normal, Snackbar.LENGTH_SHORT).show();

然后第三个参数是SnackBar的持续时间,只有三种:

1、Snackbar.LENGTH_INDEFINITE 一直显示直到另一个SnackBar出现或者主动调用了dismiss()方法
2、Snackbar.LENGTH_SHORT 显示较短的时间
3、Snackbar.LENGTH_LONG 显示较长的时间

但是官方文档是这么描述的:

either be one of the predefined lengths: LENGTH_SHORT, LENGTH_LONG, or a custom duration in milliseconds.

说是可以自定义显示时间,但是我自己试了确实不可以,应该是API文档的一个小bug,如果谁试成功了赶紧告诉我~~如果使用过Toast的话上面的应该很好理解,好了,如果你的业务中对SnackBar并没有更多的要求,那么最普通的SnackBar应该满足了,接下来看稍微高级一点的:

  • 带回调的SnackBar:如果还不太清楚回调的话可以看看这个Android回调函数机制那点事 ,讲这个之前先提一点,如果我们想更加灵活的使用Snackbar的话最好是先持有它的引用,也就是:
    private Snackbar mSnackBar
    原因很简单,你会发现上面提供的常用API中很多方法都是非静态方法并不是静态方法,你要调用的话只能通过SnackBar对象去调用。然后说SnackBar回调之前先说一下Action,SnackBar提供了一个setAction方法:
    1、setAction(int resId, View.OnClickListener listener)
    2、setAction(CharSequence text, View.OnClickListener listener)
    同样是两个重载方法,第一个参数跟前面解释的一样,第二个参数是我们熟知的对点击事件的监听,使用方法如下:
    Snackbar.make(mCoor,R.string.callback,Snackbar.LENGTH_SHORT) 
    .setAction(R.string.UNDO, new View.OnClickListener() { 
    @Override public void onClick(View v) { 
    // do something }
    }).show();
    看一下效果:

    这里写图片描述
    当我们调用了setAction方法并且传入一个字符串之后,SnackBar的右下角就会呈现出我们传入的字符串,并且这个字符串是可点击的,我们可以在点击事件里面做出响应,比如说跳转Activity或者弹出一个Toast等等,这里默认你点击了这个Action这个SnackBar是会消失的。也就是无论你的duration参数设置的是一直显示还是显示多长时间都会消失。有些人可能对右下角这个文字的颜色不满足想要改变,没问题,你想到的Google都给你想好了,SnackBar专门提供了方法来更改Action的文字颜色:
    1、setActionTextColor(ColorStateList colors)
    2、setActionTextColor(int color)
    这里第一种方式不建议用,太复杂,你要想这么用也行:
    Resources resource = (Resources) getBaseContext().getResources(); 
    ColorStateList csl = (ColorStateList) 
    resource.getColorStateList(R.color.PeachPuff); 
    mSnackBar.setActionTextColor(csl);
    这是网上找到的一种方式,但是我还是推荐使用第二种方式来更改Action的文字颜色,可以看到是我们熟悉的传入一个int型的值,我提供如下几种方式更改:
1、mSnackBar.setActionTextColor(Color.rgb(232,44,123))
2、mSnackBar.setActionTextColor(Color.BLUE)
3、mSnackBar.setActionTextColor(Color.parseColor("#FFDAB9"));

对了,我还发现一种额外的方式,我们现在使用Android Studio创建新的Project时候系统都会默认在style.xml文件夹下面生成这个:

<style name="AppTheme" parent="The
e.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> 
<item name="colorPrimary">@color/colorPrimary</item><item name="colorPrimaryDark">@color/colorPrimaryDark</item> 
<item name="colorAccent">@color/colorAccent</item> </style>

这里的<item name="colorAccent">@color/colorAccent</item>其实也可以更改Action文字颜色,而且默认的Action文字颜色就是这里设置的颜色,但是有一个缺点就是如果你改动了这里,那么很多Material Design控件的相关颜色都会改变,如果你看过我之前写的Android Design Support Library--TextInputLayout的使用你会知道TextInputLayout下划线的颜色也是通过这个属性来更改的,所以为了稳定起见还是使用官方提供的方法去更改吧,我这纯属抖个机灵。
那么回到正题,讲讲SnackBar的回调,眼尖的朋友可能发现了,我的Demo里面带回调的SnackBar在弹出和消失的时候都会有Toast通知出现,其实就是使用了SnackBar自带的

setCallback(Snackbar.Callback callback)

方法,这里需要传入一个Snackbar.Callback callback 参数,其实这个,这个Callback 是SnackBar内部的一个抽象类,它内部有两个空实现的方法:

onDismissed(Snackbar snackbar, int event)
onShown(Snackbar snackbar)

顾名思义,我们可以可以分别在这两个方法中定义出当SnackBar消失和产生时我们需要做的事,这两个方法会在SnackBar消失和产生时被回调,打个比方:

mSnackBar.setCallback(new Snackbar.Callback() { @Override public 
void onDismissed(Snackbar snackbar, int event) { 
super.onDismissed(snackbar, event); 
Toast.makeText(MainActivity.this,"SnackBar 
Dismiss",Toast.LENGTH_SHORT).show(); } @Override public void 
onShown(Snackbar snackbar) { super.onShown(snackbar); 
Toast.makeText(MainActivity.this,"SnackBar 
Show",Toast.LENGTH_SHORT).show(); } });

这样就实现了在SnackBar消失和产生时弹出Toast通知的动作,其他具体的逻辑可以自己去实现。

完全自定义你自己的SnackBar

如果你对上述使用还是不甚满意,那么接下来我教你怎么自定义你自己的SnackBar,说实话用到的场景并不多,但是学了就学个透彻,这一部分知识的灵感来自于没时间解释了,快使用Snackbar! ,SnackBar并没有提供更改背景或者其他样式的方法,但是我们可以通过查看源码来试试可不可以自定义自己样式,我们找到这么一段代码:

private Snackbar(ViewGroup parent) { mTargetParent = parent; 
mContext = parent.getContext(); 
ThemeUtils.checkAppCompatTheme(mContext); LayoutInflater 
inflater = LayoutInflater.from(mContext); mView = (SnackbarLayout) 
inflater.inflate( R.layout.design_layout_snackbar, mTargetParent, 
false);}

最后一行的inflate是不是很熟悉,我们可不可以认为Snackbar的布局就是这么加载的,这个SnackBarLayout是在SnackBar内部定义的一个继承自LinearLayout的内部类:

public static class SnackbarLayout extends LinearLayout { private 
TextView mMessageView; private Button mActionView; private int 
mMaxWidth; private int mMaxInlineActionWidth;

看到这几个变量的定义,我已经确定了上面的想法,接下来我们找到上面代码加载的那段布局:

<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="14dp" android:paddingBottom="14dp" 
android:paddingLeft="12dp" android:paddingRight="12dp" 
android:textAppearance="@style/TextAppearance.Design.Snackbar.
Message" android:maxLines="2" 
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="0dp" android:layout_marginStart="0dp" 
android:layout_gravity="center_vertical|right|end" 
android:paddingTop="14dp" android:paddingBottom="14dp" 
android:paddingLeft="12dp" android:paddingRight="12dp" 
android:visibility="gone" android:textColor="?attr/colorAccent" 
style="?attr/borderlessButtonStyle"/></merge>

看到这两个控件的ID了么

android:id="@+id/snackbar_text"
android:id="@+id/snackbar_action"
public View getView ()Returns the Snackbar's view.

这个方法可以返回我们SnackBar的View,那么这个View是什么,看源码:
那么第一个就是SnackBar左边显示的message,第二个就是我们设置了action时候显示的Button咯,这就简单了,如果你仔细看了上面提供的API文档你会发现有这么一个方法:

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

找一下mView在哪里定义的:

private final SnackbarLayout mView;mView = (SnackbarLayout) 
inflater.inflate( R.layout.design_layout_snackbar, mTargetParent, 
false);

好了,这下一切都清楚了,接下里示范一下怎么自定义你自己的SnackBar:

private View view; ....省略中间代码  view = 
mCustomSnackBar.getView();if (view != null) { 
view.setBackgroundColor(Color.parseColor("#7B68EE"));//获取Snackbar的message控件,修改字体颜色 
((TextView)view.findViewById(R.id.snackbar_text)).setTextColor(Color.parseColor("#FFDAB9")); 
//添加图标 
Snackbar.SnackbarLayout snackbarLayout = (Snackbar.SnackbarLayout) view; 
//添加自定义布局,这里布局就包含了一个ImageView 
//custom_layout是你自定义的布局 
View add_view = LayoutInflater.from(view.getContext()).inflate(R.layout.custom_layout
, null); 
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONT
ENT, LinearLayout.LayoutParams.WRAP_CONTENT); 
p.gravity = Gravity.CENTER_VERTICAL; //数字表示新加的布局在SnackBar中的位
置,从0开始,取决于你SnackBar里面有多少个子View 
snackbarLayout.addView(add_view, 0, p); }

最后一行,addView方法第二个参数表示新加的布局在SnackBar中的位置,注意不要超过总的View的个数不然会报错,message和Action text分别算一个View,其他的话注释已经写得很清楚就不一一解释了,这个代码呈现的效果如下:


这里写图片描述

项目源码
项目GitHub地址
另外,最近做了一个小Demo,主要是使用了ExplosionField 的View爆炸效果,效果图如下:


这里写图片描述

这里写图片描述

有兴趣的可以看看:GitHub地址



文/李牧羊(简书作者)
原文链接:http://www.jianshu.com/p/2654e6bda3b1
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

转载于:https://www.cnblogs.com/muyuge/p/6152136.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/356620.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

html语言及语法结构,HTML语法结构.ppt

HTML语法结构HTML超文本标识语言 HTML超文本标识语言 HTML概念 HTML(Hyper Text Markup Language 超文本标识语言) 是一种用来制作超文本文档的简单标记语言。用HTML编写的超文本文档称为HTML文档。 HTML超文本标识语言 HTML文档的编写方法 1.手 工 直 接 编 写 记事本等&#…

利用Aspose.Word控件实现Word文档的操作

Aspose系列的控件&#xff0c;功能都挺好&#xff0c;之前一直在我的Winform开发框架中用Aspose.Cell来做报表输出&#xff0c;可以实现多样化的报表设计及输出&#xff0c;由于一般输出的内容比较正规化或者多数是表格居多&#xff0c;所以一般使用Aspose.Cell来实现我想要的各…

html编码自动识别,html实体编码遇上js代码

摘要&#xff1a; 在js中单、双引号引起来的是字符串&#xff0c;如果我们要在字符串中使用单、双引号&#xff0c;需要反斜杠进行转义。而如果字符串出现在html标签中&#xff0c;我们需要做转义处理。单双引号在js代码中在js中单、双引号引起来的是字符串&#xff0c;如果我们…

jpa动态扩展sql_扩展您的JPA POJO

jpa动态扩展sql可扩展性是许多体系结构的重要特征。 它衡量是否容易&#xff08;或困难&#xff09; 它是在不影响现有核心系统功能的情况下添加或更改功能。 让我们举一个简单的例子。 假设您的公司拥有一个核心产品来跟踪体育俱乐部中的所有用户。 在您的产品体系结构中&…

手机 html 折叠效果,HTML5仿苹果手机的面板合拢折叠效果

passbook仿苹果手机的面板合拢折叠效果-html5特效.pocket{width:300px;height:460px;padding: 10px;overflow: hidden;float: left;border: 1px solid #EDEDED;margin: 4px;border-radius: 8px;box-shadow:0 -5px 30px rgba(0,0,0,0.2) inset;}.passcard {float: left;width:30…

Activiti中具有单独数据库模式的多租户

我们过去听到的一项功能请求是以多租户方式运行Activiti引擎&#xff0c;使租户的数据与其他租户的数据隔离。 当然&#xff0c;在某些云/ SaaS环境中&#xff0c;这是必须的。 几个月前&#xff0c;波恩大学的学生拉斐尔吉伦&#xff08;Raphael Gielen&#xff09;与我接触&…

dfs手写栈模板

在竞赛中如果系统栈很小的话&#xff0c;过深的递归会让栈溢出&#xff0c;这个时候我们就要自己手写栈&#xff0c;将递归转化成手工栈。 方法其实也很简单。 基本思路上&#xff0c;我们就是用栈不断的pop,push。但是何时push&#xff0c;何时pop呢&#xff1f; 在《算法导论…

html5自动把某个层放在屏幕底部,告诉你一个将 footer 保持在底部的最好方法

当你在布局网页时&#xff0c;有可能会遇到类似下面的这种情况broken_layout.png导致这一问题的原因是页面内容太少&#xff0c;无法将内容区域撑开&#xff0c;从而在 footer 下面留下一大块空白。本文将介绍一种现代化的方法&#xff0c;&#xfffd;确保 footer 始终处于页面…

前后数据交互(ajax) -- 初始化页面表格

// 初始化员工信息列表 function loadpage ( pageNum ) {var keywords $("#keywords").val();$("#tbody").html("");if ( isNaN(pageNum) ) {pageNum 1;}$.$.ajax({type: GET,url: contextPath "/getaccountList/" pageNum "…

html的扇形代码导航,CSS3--利用transform和transition属性制作扇形导航

在前面&#xff0c;我们已经讲解了transform这个属性以及案例&#xff0c;那么本文会进一步结合transform和transition两个属性&#xff0c;并制作一个简单的案例进行说明。一、transition属性说明接下来简单分析一下transition这个属性的定义以及子属性。1)ansition-property …

UCI数据

http://archive.ics.uci.edu/ml/datasets.html?format&task&att&area&numAtt&numIns&type&sortinstDown&viewtable转载于:https://www.cnblogs.com/zangrunqiang/p/5999238.html

常见的误解:这会创建多少个对象?

总览 一个常见的问题是一段代码创建多少个对象或多少个字符串。 答案通常不是您的想法&#xff0c;也不是您真正需要知道的。 了解何时创建对象是很有用的&#xff0c;但是有很多其他因素通常要考虑的重要得多&#xff0c;这可能意味着应用程序总数不是您所想的。 字符串不是一…

cvs配电保护断路器_电工电器(三)-配电电器-断路器类-剩余电流保护断路器

本文文字836&#xff0c;阅读时间6分钟左右。此系列文章 从配电电器的大类等进行慢慢阐述&#xff0c;有不足的地方 欢迎大家相互探讨交流。配电电器&#xff0c;顾名思义就是进行电力分配的设备。电&#xff0c;从发电机出来之后&#xff0c;由总线输出&#xff0c;不可能直接…

html模块殃射,【Web前端问题】webpack打包后,module模块中的函数无法在html标签的事件中调用?...

折腾了好久&#xff0c;求大佬指点~~最近才开始接触webpack以及ES6的module&#xff0c;可能理解的有问题吧。。。希望大佬来指点一下我这个菜鸟。我的想法是在一个module中定义函数&#xff0c;在HTML的中用onclick事件调用这个函数。module模块代码&#xff1a;— base.js —…

Linux网络参数设置

1、ifconfig 查询、设定网络卡与ip 设置桥接网络 # vi /etc/sysconfig/network-script/ifcfg-br0DEVICEbr0 #设备名称BOOTPROTOstatic #设置静态地址IP6INITnoMTU1500 #设置MTU连接数 (可以设定不同的MTU数值)NM_CONTROLLEDnoONBOOTyesIPADDR…

delhpi7 tcombobox清楚重复项_专利数据统计中需要搞清楚的首要问题(2)

上一篇专利数据统计中需要搞清楚的首要问题(1)介绍了通过合并申请号避免重复统计&#xff0c;理清了专利篇数和专利件数的问题&#xff0c;那么还有一类统计就是对发明项数的统计&#xff0c;这里就涉及到对同一项发明的重复统计问题。上一篇介绍的相同申请号但不同公开号的专利…

【Electron】Electron开发入门(八):自定义electron框架外壳(shell)的菜单(Menu)...

1.自定义electron框架外壳&#xff08;shell&#xff09;的菜单&#xff08;Menu&#xff09; electron的main.js里代码&#xff1a; const Menu require(electron).Menu; var template [{label: 关闭,click: function () { win.close();console.log("关闭")},// s…

交通大数据应用细分_盈海科技 | 交通大数据可视化“掘金”数据价值

面对日益拥堵的交通状况智能交通布局虽在不断完善但交通管理依旧收效甚微问题究竟出在了哪里&#xff1f;数据独立存储难以融合应用数据内在规律难寻数据可视化程度低……问题繁多 困难重重怎么办&#xff1f;&#xff1f;&#xff1f;交通大数据可视化解决方案上岗啦&#xff…

书评– Kubernetes Up&Running,作者:Kelsey Hightower

欢呼&#xff01; 正如我在以前的帖子中所写的那样&#xff0c;当您开始研究和使用所有这些新颖的&#xff0c;有光泽的容器/编排技术时&#xff0c;很有可能最终导致您的翻译“迷失”。 很多信息&#xff0c;很多技术&#xff0c;很多开发 &#xff0c;很多承诺&#xff0c;很…

relative布局html,CSS的四种布局方式static/relative/fixed/absolute

staticstatic布局是HTML元素默认的布局方式&#xff0c;并且static布局的元素不会受到top/left/bottom/right属性的影响。布局元素的位置即其在标准文档流中的位置。relative相对布局是相对其在标准文档流中的位置而言的。设置其top/left/bottom/right属性会使该元素脱离标准文…