Snackbar和Toast的花式使用,系统Toast的存在的问题

系统toast存在的问题:

https://mp.weixin.qq.com/s/HQoAa5h-u8q32iWhs7dz_w

Foreword

这一篇是建立在我赌5毛你没见过这样的SpannableString基础上的,所以不会使用SpanUtils的小伙伴快去看看吧。

这一篇我会写得详尽一些,毕竟是为了一劳永逸,让大家也尽可能了解我是怎么做到的,这里,我会用图文结合的方式来为大家开车,好了,开车,嘟嘟嘟嘟~。

Introduce

Snackbar

首先,我介绍下Snackbar,它是support.design包下的一个widget,和Toast用途一样,可用来提示用户操作后的结果,但显示一般是在屏幕底部,较大的设备会在左下角显示,而且同一时间只能显示一条,它可以自动消失,也可以用户手动取消,但和Toast不同的是它会伴随Activity的结束而消失,其在绝对布局中还支持侧滑消失,其用法也和Toast很像,具体基本使用可以自行上网了解,我这里主要讲解其高端使用。

下面我简单介绍一下SnackbarUtils的API,后面演示我会一一细说。

Snackbar相关→SnackbarUtils.javaDemo

 
  1. with : 设置snackbar依赖view

  2. setMessage : 设置消息

  3. setMessageColor: 设置消息颜色

  4. setBgColor : 设置背景色

  5. setBgResource : 设置背景资源

  6. setDuration : 设置显示时长

  7. setAction : 设置行为

  8. show : 显示snackbar

  9. showSuccess : 显示预设成功的snackbar

  10. showWarning : 显示预设警告的snackbar

  11. showError : 显示预设错误的snackbar

  12. dismiss : 消失snackbar

  13. getView : 获取snackbar视图

  14. addView : 添加snackbar视图

下面我来为其演示,说了那么多,总算要上图了。

short_snackbar

有些朋友可能会惊讶,卧槽,怎么和我平时看到的Snackbar不太一样,顶部是两圆角,前面还有图标,下面请听老司机分析,先上个代码压压惊。

 
  1. SnackbarUtils.with(snackBarRootView)

  2. .setMessage(getMsg(R.string.snackbar_short))

  3. .setMessageColor(Color.WHITE)

  4. .setBgResource(R.drawable.shape_top_round_rect)

  5. .show();

实现如上效果,只需要以上代码即可,首先我们需要为Snackbar传递其parent视图,我用的是with()操作,用过Glide的小伙伴们肯定都知道with(),我觉得这词很好,所以也就拿来用了,后面setMessage()就是设置展示的消息了,其中参数为getMsg(xxx),这是现实图标的关键,下面放上源码。

 
  1. private SpannableStringBuilder getMsg(@StringRes int resId) {

  2. return new SpanUtils()

  3. .appendLine(getString(resId))

  4. .setFontSize(24, true)

  5. .setIconMargin(R.mipmap.ic_launcher, 32, SpanUtils.ALIGN_CENTER)

  6. .append(" ").setFontSize(0)

  7. .create();

  8. }

看到了吧,这里我使用的是SpannableString,因为展示的消息的容器是TextView,所以可以用各种SpannableString,搭配上我上一篇文章我赌5毛你没见过这样的SpannableString,用起来不要太爽,这里我用的是它的setIconMargin()来设置图标,因为这是属于段落型的SpannableString,所以我要把appendLine()产生的新行,用字体大小为0append(" ").setFontSize(0)代替,从而看起来只有一行存在。为了方便起见,我把设置消息字体颜色setMessageColor()和设置背景色setBgColor()及设置背景资源setBgResource()抽离了出来,所以顶部的两个圆角实现也是一语道破了,其用的是setBgResource()

图中显示的第二个Snackbar右侧还有可点击按钮,源码如下所示。

 
  1. SnackbarUtils.with(snackBarRootView)

  2. .setMessage(getMsg(R.string.snackbar_short))

  3. .setMessageColor(Color.WHITE)

  4. .setBgResource(R.drawable.shape_top_round_rect)

  5. .setAction(getString(R.string.snackbar_click), Color.YELLOW, new View.OnClickListener() {

  6. @Override

  7. public void onClick(View v) {

  8. ToastUtils.showShort(getString(R.string.snackbar_click));

  9. }

  10. })

  11. .show();

这里只比之前多了个setAction(),就是设置点击相关的文字,字体颜色及点击事件。

默认如果不写setDuration(),那么Snackbar的显示时长为短时,Snackbar显示时长共包括三种,可以在setDuration()中传入SnackbarUtils.LENGTH_SHORTSnackbarUtils.LENGTH_LONGSnackbarUtils.LENGTH_INDEFINITE分别表示短时、长时、永久,这里我就不重复演示了。

如果SpanUtils都满足不了各位大佬们的需求,别急,这里柯基实现了其他的接口来帮助你们,这里提醒一下,Snackbar追求的是简洁明了,不要太过花里胡哨哈。

下面展示一下自定义的Snackbar,如下图所示。

custom_snackbar

结合以下源码。

 
  1. SnackbarUtils.with(snackBarRootView)

  2. .setBgColor(Color.TRANSPARENT)

  3. .setDuration(SnackbarUtils.LENGTH_INDEFINITE)

  4. .show();

  5. ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

  6. SnackbarUtils.addView(R.layout.snackbar_custom, params);

这里可以看到我们把Snackbar的背景设为了透明setBgColor(Color.TRANSPARENT),然后先调用了show(),因为只有先show()出来之后,我们才能获取到Snackbar的视图,然后对其加入我们自定义视图addView()即可。

但显示的第二个Snackbar还拥有点击消失的功能,这又是怎么实现的呢,其实答案已经呼之欲出了,我们只需要得到该视图即可,也就是API中的getView(),然后就是你们随心所欲的操作了,源码如下所示。

 
  1. View snackbarView = SnackbarUtils.getView();

  2. if (snackbarView != null) {

  3. TextView tvSnackbarCustom = (TextView) snackbarView.findViewById(R.id.tv_snackbar_custom);

  4. tvSnackbarCustom.setText("点我可消失");

  5. snackbarView.setOnClickListener(new View.OnClickListener() {

  6. @Override

  7. public void onClick(View v) {

  8. SnackbarUtils.dismiss();

  9. }

  10. });

  11. }

在此,Snackbar的高端玩法已经基本介绍完毕,除此之外,柯基还为大佬们封装了常用的几种,showSuccessshowWarningshowError,其效果如下图所示。

others_snackbar

方便快捷调用代码如下所示。

 
  1. case R.id.btn_show_success:

  2. SnackbarUtils.with(snackBarRootView)

  3. .setMessage(getMsg(R.string.snackbar_success))

  4. .showSuccess();

  5. break;

  6. case R.id.btn_show_warning:

  7. SnackbarUtils.with(snackBarRootView)

  8. .setMessage(getMsg(R.string.snackbar_warning))

  9. .showWarning();

  10. break;

  11. case R.id.btn_show_error:

  12. SnackbarUtils.with(snackBarRootView)

  13. .setMessage(getMsg(R.string.snackbar_error))

  14. .showError();

  15. break;

好了,第一部分Snackbar的花式使用已介绍完毕,下面来说说大同小异的Toast

Toast

Toast这玩意家喻户晓,其基本使用我就不介绍了,需要注意的就是在show()之前要把之前的Toast取消掉,否则的话Toast会在队列中排队等待,造成不能及时得到当前需要的;还有一点就是异步show()的话也会报错,这些最基本的在ToastUtils都有解决。我们来看下其API介绍。

吐司相关→ToastUtils.javaDemo

 
  1. setGravity : 设置吐司位置

  2. setView : 设置吐司view

  3. getView : 获取吐司view

  4. setBackgroundColor : 设置背景颜色

  5. setBackgroundResource: 设置背景资源

  6. setMessageColor : 设置消息颜色

  7. showShortSafe : 安全地显示短时吐司

  8. showLongSafe : 安全地显示长时吐司

  9. showShort : 显示短时吐司

  10. showLong : 显示长时吐司

  11. cancel : 取消吐司显示

可以看到其包括setView()getView(),没错,有了它们,就可以设置自定义视图了。下面我从最基本用法开始介绍吧,先上图。

normal_toast

可以看到包括短时和长时的Toast两类,我只介绍其一,另一种同理,显示短时Toast的源码如下所示。

 
  1. case R.id.btn_show_short_toast_safe:

  2. new Thread(new Runnable() {

  3. @Override

  4. public void run() {

  5. ToastUtils.showShortSafe(R.string.toast_short_safe);

  6. }

  7. }).start();

  8. break;

  9. case R.id.btn_show_short_toast:

  10. ToastUtils.showShort(R.string.toast_short);

  11. break;

可以看到我在异步的时候调用的是showShortSafe(),这样就可以安全地使用了,是不是很简洁,只需要传入你要显示的内容即可,而且连续show()也没什么问题。

作为常用操作,还支持设置文字颜色、背景颜色及背景资源,我们看下演示。

font_bg_toast

源码很简单,我就不做过多解释了,如下所示。

 
  1. case R.id.btn_show_green_font:

  2. ToastUtils.setMessageColor(Color.GREEN);

  3. ToastUtils.showLong(R.string.toast_green_font);

  4. break;

  5. case R.id.btn_show_custom_bg:

  6. ToastUtils.setBgResource(R.drawable.shape_round_rect);

  7. ToastUtils.showLong(R.string.toast_custom_bg);

  8. break;

花式使用?没错,又到了我们的SpanUtils上场了,所以,没了解的小伙伴们还不赶快去看看我赌5毛你没见过这样的SpannableString来提升逼格,再来秀一波。

span_toast

源码如下,和之前介绍Snackbar大相径庭,这里就不细说了。

 
  1. case R.id.btn_show_span:

  2. ToastUtils.showLong(new SpanUtils()

  3. .appendLine(getString(R.string.toast_span))

  4. .setFontSize(24, true)

  5. .setIconMargin(R.mipmap.ic_launcher, 32, SpanUtils.ALIGN_CENTER)

  6. .append(" ").setFontSize(0)

  7. .create());

  8. break;

同理,如果SpanUtils满足不了你的需求,那我们就自定义吧,不过Toast真的要这么花哨么,这是在搞事情,上图了。

custom_toast

源码如下,用得真是太简单了,为你们解放双手。

 
  1. case R.id.btn_show_custom_view:

  2. ToastUtils.setView(R.layout.toast_custom);

  3. ToastUtils.showLong("");

  4. break;

last but not least,Toast还支持位置的变动,我就演示一下居中显示,如下所示。

middle_toast

源码如下,通俗易懂。

 
  1. case R.id.btn_show_middle:

  2. ToastUtils.setGravity(Gravity.CENTER, 0, 0);

  3. ToastUtils.showLong(R.string.toast_middle);

  4. break;

好了,Toast相关已介绍完毕。

Conclusion

大佬们不用担心使用SnackbarUtilsToastUtils会出现内存泄漏的问题,我一开始设计的时候就使用了弱引用来规避这个问题,所以还不放心大胆来使用他们吧,再配合上SpanUtils,你们也可以玩出花来了,独乐乐不如众乐乐。

猜你喜欢

转载自blog.csdn.net/m0_38058826/article/details/84941389