当前位置: 首页 > 编程日记 > 正文

SnackbarUtilDemo【Snackbar的封装类】

版权声明:本文为HaiyuKing原创文章,转载请注明出处!

前言

这个工具类参考的是《没时间解释了,快使用Snackbar!——Android Snackbar花式使用指南》,代码几乎一样,所以想要了解具体原理或者更详细信息请阅读参考资料。

这里只是做了一个简单的记录。

在项目中到底是使用Toast还是Snackbar,可以从这一方面考虑,Toast会显示在输入法键盘上方,Snackbar不会显示在输入法键盘上方(会被输入法键盘遮挡住);

效果图

代码分析

SnackbarUtil.java:Snackbar封装类

使用步骤

一、项目组织结构图

注意事项:

1、  导入类文件后需要change包名以及重新import R文件路径

2、  Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

二、导入步骤

1、在build.gradle中引入design支持库【版本号跟appcompat保持一致】

apply plugin: 'com.android.application'android {compileSdkVersion 28defaultConfig {applicationId "com.why.project.snackbarutildemo"minSdkVersion 16targetSdkVersion 28versionCode 1versionName "1.0"testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}
}dependencies {implementation fileTree(dir: 'libs', include: ['*.jar'])implementation 'com.android.support:appcompat-v7:28.0.0'implementation 'com.android.support.constraint:constraint-layout:1.1.3'testImplementation 'junit:junit:4.12'androidTestImplementation 'com.android.support.test:runner:1.0.2'androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'//引入design库implementation 'com.android.support:design:28.0.0'
}

2、将SnackbarUtil复制到项目中

package com.why.project.snackbarutildemo.utils;import android.graphics.Color;
import android.support.design.widget.Snackbar;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;import com.why.project.snackbarutildemo.R;/*** Used Snackbar封装类* https://www.jianshu.com/p/cd1e80e64311*/
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 = 0xffFE4949;//红色错误提示:原方案-f44336public static int green = 0xffa1c45a;//绿色成功提示:原方案-4caf50public static int blue = 0xff54B0FF;//蓝色普通提示:原方案-2195f3public static int orange = 0xffFF8438;//橙色警告提示:原方案-ffc107/*** 短显示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【用于添加图标】【Google不建议】* @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.java

三、使用方法

activity_main.xml布局文件(其实没有重要代码)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><Buttonandroid:id="@+id/btn_info"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="弹出Info类型的Snackbar"android:layout_margin="10dp"/><Buttonandroid:id="@+id/btn_confirm"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="弹出Confirm类型的Snackbar"android:layout_margin="10dp"/><Buttonandroid:id="@+id/btn_warning"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="弹出Warning类型的Snackbar"android:layout_margin="10dp"/><Buttonandroid:id="@+id/btn_alert"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="弹出Alert类型的Snackbar"android:layout_margin="10dp"/></LinearLayout>
activity_main.xml

在Activity中使用SnackbarUtil.java类

package com.why.project.snackbarutildemo;import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;import com.why.project.snackbarutildemo.utils.SnackbarUtil;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);((Button)findViewById(R.id.btn_info)).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {/*这个view是有讲究的——我们传入的view经过了findSuitableParent()方法的包装。1.当传入的View不为空时,如果我们在布局中发现了CoordinatorLayout布局,那么View就是CoordinatorLayout;2.如果没有CoordinatorLayout布局,我们就先找到一个id为android.R.id.content的FrameLayout(这个布局是最底层的根布局),将View设置为该FrameLayout;3.其他情况下就使用View的Parent布局,一直到这个View不为空。*/SnackbarUtil.ShortSnackbar(view,"已超出范围,请重新选择",SnackbarUtil.Info).show();}});((Button)findViewById(R.id.btn_confirm)).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {/*这个view是有讲究的——我们传入的view经过了findSuitableParent()方法的包装。1.当传入的View不为空时,如果我们在布局中发现了CoordinatorLayout布局,那么View就是CoordinatorLayout;2.如果没有CoordinatorLayout布局,我们就先找到一个id为android.R.id.content的FrameLayout(这个布局是最底层的根布局),将View设置为该FrameLayout;3.其他情况下就使用View的Parent布局,一直到这个View不为空。*/SnackbarUtil.ShortSnackbar(view,"保存成功",SnackbarUtil.Confirm).show();}});((Button)findViewById(R.id.btn_warning)).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {/*这个view是有讲究的——我们传入的view经过了findSuitableParent()方法的包装。1.当传入的View不为空时,如果我们在布局中发现了CoordinatorLayout布局,那么View就是CoordinatorLayout;2.如果没有CoordinatorLayout布局,我们就先找到一个id为android.R.id.content的FrameLayout(这个布局是最底层的根布局),将View设置为该FrameLayout;3.其他情况下就使用View的Parent布局,一直到这个View不为空。*/SnackbarUtil.ShortSnackbar(view,"标题不能为空",SnackbarUtil.Warning).show();}});((Button)findViewById(R.id.btn_alert)).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {/*这个view是有讲究的——我们传入的view经过了findSuitableParent()方法的包装。1.当传入的View不为空时,如果我们在布局中发现了CoordinatorLayout布局,那么View就是CoordinatorLayout;2.如果没有CoordinatorLayout布局,我们就先找到一个id为android.R.id.content的FrameLayout(这个布局是最底层的根布局),将View设置为该FrameLayout;3.其他情况下就使用View的Parent布局,一直到这个View不为空。*/SnackbarUtil.ShortSnackbar(view,"保存失败",SnackbarUtil.Alert).setAction("重试", new View.OnClickListener() {@Overridepublic void onClick(View view) {Toast.makeText(MainActivity.this,"重试",Toast.LENGTH_SHORT).show();}}).setActionTextColor(Color.parseColor("#ffffff")).show();}});}
}

混淆配置

参考资料

没时间解释了,快使用Snackbar!——Android Snackbar花式使用指南

SnackbarUtils:一行代码搞定Snackbar

Design库-SnackBar属性详解

项目demo下载地址

https://github.com/haiyuKing/SnackbarUtilDemo

相关文章:

java通过代理访问网络

使用代理方式连接到网络 Testpublic void t13(){String charset "utf-8" ; String proxyHost "代理地址" ; int proxyPort 1234 ; //代理端口String proxyUrsername "登陆代理服务器的用户名" ; String proxyPassword "登陆代理服务器…

poj2503 Babelfish

跟poj3349很类似的题目&#xff0c;这题还稍简单。用qsort快速排序和二分查找可以很轻松AC。以下是代码&#xff1a; Run IDUserProblemResultMemoryTimeLanguageCode LengthSubmit Time5135234zen_chou2503Accepted2356K547MSC1212B2009-05-11 20:12:26Code1 #include <std…

(C语言)一种简易记法:生成[a,b]范围内的随机整数

1. 添加头文件 #include<stdlib.h> #include<time.h> 2. 初始化随机种子 srand((unsigned)time(NULL)); 3. 确定元素个数b-a1&#xff0c;以及最小元素 printf("%d",rand()%(b-a1)a);//生成[a,b]之间的数 printf("%d",rand()%1001);//生成…

IE和火狐都支持的方法(输入用户名和密码后按下 enter 键)

在Firefox中老报"event is not defined”错误&#xff01;原因是因为在Firefox中使用了不同的事件对象模型,不同于IE Dom&#xff0c;用的是W3C Dom。 document.οnkeydοwnfunction mykeyDown(e){ //compatible IE and firefox because there is not event in fir…

数据库中存储与读取文件

if exists (select * from dbo.sysobjects where id object_id(N[dbo].[p_binaryIO]) and OBJECTPROPERTY(id, NIsProcedure) 1)drop procedure [dbo].[p_binaryIO]GO /*--bcp 实现二进制文件的导入导出 支持image,text,ntext字段的导入/导出 image适合于二进制文件,包括:Wor…

洛谷P3723 [AH2017/HNOI2017]礼物(FFT)

传送门 首先&#xff0c;两个数同时增加自然数值相当于只有其中一个数增加&#xff08;此增加量可以小于0&#xff09; 我们令$x$为当前的增加量&#xff0c;${a},{b}$分别为旋转后的两个数列&#xff0c;那么$$ans\sum_{i1}^n(a_ix-b_i)^2$$ 然后把第$i$项提出来并展开&#x…

1035 插入与归并

1. 这一题&#xff0c;首先要会插入排序和归并排序的写法。对于归并排序&#xff0c;可以用非递归sort最简便。把每一趟的结果存进二维数组。 2. 单独封装一个函数&#xff0c;比较两个一维数组是否完全一样。 3. 由于归并比插入的复杂度低&#xff0c;趟数少&#xff0c;所以…

代码设置LinearLayout的高度

问题描述我想把这个LinearLayout宽度设置成为FILL_PARENT&#xff0c;源码如下LinearLayout checkboxLinearLayout (LinearLayout) getLayoutInflater().inflate(R.layout.checkboxdoitem, null);LayoutParams params (LayoutParams) checkboxLinearLayout.getLayoutParams();…

精通Spring Boot —— 第十五篇:使用@ControllerAdvice处理异常

在Spring 3.2中&#xff0c;新增了ControllerAdvice、RestControllerAdvice 注解&#xff0c;可以用于定义ExceptionHandler、InitBinder、ModelAttribute&#xff0c;并应用到所有RequestMapping、PostMapping&#xff0c; GetMapping注解中。接下来我将通过代码展示如何使用这…

架构设计之分布式文件系统

1&#xff1a;类图 2&#xff1a;数据结构 create table TBCOFILE ( FILEID INTEGER not null, FILETIME DATE, TYPE VARCHAR2(10), USERID INTEGER, IP VARCHAR2(20), APPTYPE INTEGER default 0) 3&#xff1a;开发步骤 1&#xff1a;从数据库申…

1029 Median

1. 开始测试点3和6答案错误&#xff0c;原因是没有考虑到&#xff0c;给的两个数列有可能长度相差很大&#xff0c;某个数列还没到中位数&#xff0c;就结束了。 2. 这题的底子是用two pointers按照非递减的顺序合并两个数列&#xff0c;无非是再确定一下中间那个数的下标&…

理解系统底层的概念是多么重要

理解系统底层的概念是多么重要 ——趋势科技邹飞评《程序员的自我修养》 关于《程序员的自我修养》这本书&#xff0c;最初是在和博文的周筠老师MSN上谈起&#xff0c;当时听周老师提及这本书是一本关于链接和装载等系统软件知识的书籍&#xff0c;当时就很感兴趣&#xff0c;因…

session删除

删除一个session值&#xff1a; session_unset(变量); session_destroy(变量); 删除一个cookie&#xff1a; 注意第二个参数中手册中的说明是&#xff1a; Cookie 必须用和设定时的同样的参数才能删除。如果其值一个空字符串&#xff0c;或者是 FALSE&#xff0c;并且其它的参数…

Android学习路线

Android学习路线 第一阶段&#xff1a;Java面向对象编程 1.Java基本数据类型与表达式&#xff0c;分支循环。 2.String和StringBuffer的使用、正则表达式。 3.面向对象的抽象&#xff0c;封装&#xff0c;继承&#xff0c;多态&#xff0c;类与对象&#xff0c;对象初始化和回…

1048 Find Coins(two pointers解法)

1. 很典型的双指针的应用&#xff0c;将数组按照非降排列&#xff0c;两个指针从一头一尾开始包抄&#xff0c;若等于&#xff08;等于要放在第一个&#xff09;则返回结果结束程序&#xff0c;小于则左指针右移&#xff0c;大于则右指针左移。 2. 起初还担心&#xff0c;如果…

TCP/IP 协议理解

TCP/IP 协议&#xff08;Transmission Control Protocol / internet Protocol&#xff09;&#xff0c;因特网互联协议&#xff0c;又名网络通讯协议。通俗而言&#xff1a;TCP负责发现传输的问题&#xff0c;一有问题就发出信号&#xff0c;要求重新传输&#xff0c;直到所有数…

Webhint开源了一种代码检查工具

Webhint项目提供了一种用于检查代码的可访问性、性能和安全的开源检查&#xff08;Linting&#xff09;工具。在创建Web站点和应用中&#xff0c;有越来越多的细节问题亟待完善。为此&#xff0c;Webhint力图帮助开发人员标记这些细节。\\Webhint以命令行接口&#xff08;CLI&a…

SHAREPOINT爬网设置

F:\2009年\MOSS档案 http://share:30088/default.aspx 进入管理中心 共享服务管理-SharedServices1-搜索设置-内容源和爬网计划-本地 Office SharePoint Server 网站-下拉- -编辑-爬网计划-完全(增量)爬网-创建计划 - 对该内容源启动完全爬网-勾选上。 一、 爬网设置&#xff…

1093 Count PAT‘s

这题出现在“活用递推”专题下面&#xff0c;所谓递推就是这一步的结果和上一步的结果有直接联系。对于本题来说&#xff0c;从左到右&#xff0c;记到当前位置&#xff0c;一共出现的P的个数&#xff0c;如果当前位置是P&#xff0c;则个数就是上一位的加1&#xff0c;否则等于…

拜托,面试别再问我时间复杂度了!!!

最烦面试官问&#xff0c;“为什么XX算法的时间复杂度是OO”&#xff0c;今后&#xff0c;不再惧怕这类问题。 快速排序分为这么几步&#xff1a; 第一步&#xff0c;先做一次partition&#xff1b; partition使用第一个元素tarr[low]为哨兵&#xff0c;把数组分成了两个半区&a…

C#和JavaScript的简单互交

转自&#xff1a;http://cgxcn.blog.163.com/blog/static/132312422009426112558831/ 1.asp.net呼叫js Response.Write("<script languagejavascript>"); Response.Write("alert(登峰欢迎您 );" ); …

读阮一峰对《javascript语言精粹》的笔记,我有疑问。

《javascript语言精粹》是一本很棒的书籍&#xff0c;其中作者在附录列出了12种他所认为的javascript语言中的糟粕。 我最近开始跟读前端前辈的博客&#xff0c;其中读到了阮一峰的《12种不宜使用的Javascript语法》&#xff0c;有一个疑问&#xff1a; 文如下&#xff1a; 9. …

1008 Elevator

思路如下&#xff1a;用一个整型数组存楼层&#xff0c;0号元素为0(开始停在0层)&#xff0c;每读入一个元素&#xff0c;和上一个比较&#xff0c;更大说明是上升&#xff0c;总时长加上楼层差*6&#xff0c;反之说明是下降&#xff0c;总时长加上楼层差*4。最后再管停留时间&…

软件安全性能測试(转载)

近来&#xff0c;在我负责的公司某软件产品的最后測试工作&#xff0c;经常被问到这样一个问题&#xff1a;在做測试过程中&#xff0c;我们的软件产品在安全性方面考虑了多少&#xff1f;应该怎样測评一个软件究竟有多安全&#xff1f; 这个软件因为涉及客户商业上重要的…

org.springframework.data.redis 一次连接获取特定key所有k-v(pipeline)

2019独角兽企业重金招聘Python工程师标准>>> 当我们需要一次性获取在redis中以hash方式存储的所有key-value时&#xff0c;我们可以使用下面的方式来获取。 public void testGetMore() throws IOException {RedisCallback<List<Object>> pipelineCallba…

[网络应用]Flash中鼠标手势及Ctrl+T问题{Firefox}

想说这个问题很久了&#xff0c;也是对Flash的一点点小小的不满。 当你在浏览youku&#xff0c;56&#xff0c;Youtube&#xff0c;土豆&#xff0c;Kou6上的视频时&#xff0c;是不是会发现你的CtrlT命令不凑效了。 当你在打开一个Flash全站时&#xff0c;或者鼠标焦点在一个令…

(C++)一行代码递归实现辗转相除法

定理&#xff1a;两个整数的最大公约数等于其中较小的那个数和两数相除余数的最大公约数。 int gcd(int a,int b){return !b?a:gcd(b,a%b); } 这里递归边界是 gcd(a,0)a; 递归式是 gcd(a,b)gcd(b,a%b);

【C#】Web页面传值小结-

1. 使用QueryString变量 QueryString是一种非常简单的传值方式&#xff0c;他可以将传送的值显示在浏览器的地址栏中。如果是传递一个或多个安全性要求不高或是结构简单的数值时&#xff0c;可以使用这个方法。但是对于传递数组或对象的话&#xff0c;就不能用这个方法了…

分享:用promise封装ajax

用promise封装ajaxvar ajaxOptions {url: url,method: GET,async: true,data: null,dataType: text, } function ajax(protoOptions) {var options {};for(var i in ajaxOptions){options[i] protoOptions[i] || ajaxOptions[i];}return new Promise(function(resolve, reje…

1049 Counting Ones

1. 这一题起初我用递归的方式&#xff0c;还写了一个数整数有多少个1的函数&#xff0c;OneNum[i] OneNum[i-1]countOne(i);毫不意外地出现了段错误&#xff0c;也就是递归调用的次数太多。 2. 看了参考书&#xff0c;得到了思路上的启发&#xff1a; 给定一个数12&#xff…