说到Android Toast,几乎都很熟悉吧,下面讲讲怎么实现下面几种场景:

1、连续点击一个按钮,每次都产生一个新的Toast并且调用show方法

  问题:触发了toast以后,toast内容会一直排着队的显示出来,不能很快的消失

2、连续点击一个按钮,缓存一个Toast,每次都调用show方法

  推荐:这种方式体验感觉最好,Toast消失的计时会从最后一次show之后才开始计算,还可以通过setText设置不同的内容

3、连续点击一个按钮,缓存一个Toast,每次先调用cancel再调用show方法

  问题:这里有坑,可能cancel之后就show不出来了

4、别人封装的一个列子,介绍了Toast其他的一些问题


下面看下上面1-3种方式的代码写法:

1、连续点击一个按钮,每次都产生一个新的Toast并且调用show方法,这个没什么好说的,都会写

Toast.makeText(context, "要显示的提示", Toast.LENGTH_LONG).show();

2、连续点击一个按钮,缓存一个Toast,每次都调用show方法(推荐写法,体验比较好)

 private Toast mShowingToast;
private void showTestToast() {
// mActivity是一个Activity对象,弹Toast一般用Activity类型的Context
if (mShowingToast == null) {
mShowingToast = Toast.makeText(mActivity, "要显示的提示", Toast.LENGTH_LONG);
}
mShowingToast.show();
}

3、连续点击一个按钮,缓存一个Toast,每次先调用cancel再调用show方法 (容易踩坑的地方)

private Toast mShowingToast;
private void showTestToast() {
// mActivity是一个Activity对象,弹Toast一般用Activity类型的Context
if (mShowingToast == null) {
mShowingToast = Toast.makeText(mActivity, "要显示的提示", Toast.LENGTH_LONG);
}
mShowingToast.cancel();
mShowingToast.show();
// 会发现cancel之后调用show是show不出来的
}

上面这种方式会发现Toast显示不出来,改下写法也许读者能猜到为什么

private Toast mShowingToast;
// 主线程的Handler对象
private Handler mHandler = new Handler(Looper.getMainLooper());
private void showTestToast() {
// mActivity是一个Activity对象,弹Toast一般用Activity类型的Context
if (mShowingToast == null) {
mShowingToast = Toast.makeText(mActivity, "要显示的提示", Toast.LENGTH_LONG);
}
mShowingToast.cancel();
mHandler.postDelayed(
new Runnable() {
@Override
public void run() {
mShowingToast.show(); // 会发现延迟之后就显示出来了
}
}, 200
); // 这个时间是自己拍脑袋写的,不影响体验就好,试过使用post也不行
}

为什么呢?可能是同步异步的问题,有可能show操作被后续执行的cancel给覆盖了,所以不生效,看了下源码也没具体看出来

/**
* Show the view for the specified duration.
*/
public void show() {
if (mNextView == null) {
throw new RuntimeException("setView must have been called");
} INotificationManager service = getService();
String pkg = mContext.getOpPackageName();
TN tn = mTN;
tn.mNextView = mNextView; try {
service.enqueueToast(pkg, tn, mDuration);
} catch (RemoteException e) {
// Empty
}
} /**
* Close the view if it's showing, or don't show it if it isn't showing yet.
* You do not normally have to call this. Normally view will disappear on its own
* after the appropriate duration.
*/
public void cancel() {
mTN.hide(); try {
getService().cancelToast(mContext.getPackageName(), mTN);
} catch (RemoteException e) {
// Empty
}
} 这是Toast内部内TN的一个方法 /**
* schedule handleHide into the right thread
*/
@Override
public void hide() {
if (localLOGV) Log.v(TAG, "HIDE: " + this);
mHandler.post(mHide);
}

如果有读者知道上述问题的原因,欢迎回帖

参考文章:

http://blog.csdn.net/goodding/article/details/8792628

http://blog.csdn.net/arui319/article/details/7022392

Android Toast cancel和show 不踩中不会知道的坑的更多相关文章

  1. 2018-11-20-UWP-开发中,需要知道的1000个问题

    title author date CreateTime categories UWP 开发中,需要知道的1000个问题 lindexi 2018-11-20 09:28:53 +0800 2018- ...

  2. PHP中你应该知道的require()文件包含的正确用法

    以前看一些PHP框架源码的时候,很奇怪在文件包含的时候,会用dirname(__FILE__)来拼凑文件路径,不知道这样做有什么好处,后来终于发现了其中的缘由. 我们来看一个简单的例子: 有a,b,c ...

  3. CLR中你想知道的事

    CLR是什么? CLR 公共语言运行时,是一个可由多个语言共同使用的运行环境,核心(内存管理,程序集加载,安全性,异常处理和多线程) Visual Studio是一种编译器,编译器也可称为语法检查器和 ...

  4. Android Toast 设置到屏幕中间,自定义Toast的实现方法,及其说明

    http://blog.csdn.net/wangfayinn/article/details/8065763 Android Toast用于在手机屏幕上向用户显示一条信息,一段时间后信息会自动消失. ...

  5. Android Toast的多功能封装——Android开发之路1

    Android封装实现各种功能的Toast GitHub地址:https://github.com/SibreiaDante/ToastUtils 效果图: 方法封装如下: showSingleton ...

  6. Android Toast 封装,避免Toast消息覆盖,替换系统Toast最好用的封装

    Android Toast 封装,避免Toast消息覆盖,无阻塞,等强大功能   ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...

  7. Android Toast效果

    Android Toast效果是一种提醒方式,在程序中使用一些短小的信息通知用户,过一会儿会自动消失,实现如下: FirstActivity.java package org.elvalad.acti ...

  8. [Android] Toast问题深度剖析(二)

    欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 作者: QQ音乐技术团队 题记 Toast 作为 Android 系统中最常用的类之一,由于其方便的api设计和简洁的交互体验,被我们所广泛采用 ...

  9. robotframework + appium 获取android toast

    android toast 获取主要方式是在出现toast的时候查找元素:xpath=//*[contains(@text,'记同步')]  ,该xpath 表示为toast信息含有  "记 ...

随机推荐

  1. datatables服务器端分页要点

    背景:当要查询大量数据的时候,有datatables自身的分页,明显查询比较慢,这是要使用服务器端分页 参数:"bServerSide": true, "fnServer ...

  2. ASP.NET跨平台实践:无需安装Mono的Jexus“独立版”

    在Linux上运行ASP.NET网站或WebApi的传统步骤是,先安装libgdiplus,再安装mono,然后安装Jexus.在这个过程中,虽然安装Jexus是挺简便的一件事,但是安装mono就相对 ...

  3. [译]MVC网站教程(一):多语言网站框架

    本文简介 本博文介绍了 Visual Studio 工具生成的 ASP.NET MVC3 站点的基本框架:怎样实现网站的语言的国际化与本地化功能,从零开始实现用户身份认证机制,从零开始实现用户注册机制 ...

  4. 走向面试之数据库基础:三、SQL进阶之变量、事务、存储过程与触发器

    一.变量那点事儿 1.1 局部变量 (1)声明局部变量 DECLARE @变量名 数据类型 ) DECLARE @id int (2)为变量赋值 SET @变量名 =值 --set用于普通的赋值 SE ...

  5. Nodejs之MEAN栈开发(一)---- 路由与控制器

    因为工作需要,最近再次学习了node,上一次学习node是2014年,纯粹是个人兴趣,学了入门之后没有运用,加上赶别的项目又不了了之.这次正好捡起来.废话不多说,这里的MEAN指的是Mongodb.E ...

  6. MySQL HASH分区

    200 ? "200px" : this.width)!important;} --> 介绍 基于给定的分区个数,将数据分配到不同的分区,HASH分区只能针对整数进行HASH ...

  7. spring-boot 和 docker 集成

    描述 java 的 Spring是一个很火的框架,Spring boot 这个也不用说了,Docker 近年也很火热, 本文就介绍下我在 Spring boot + Docker的集成一些经验 :) ...

  8. Objective-C 装饰模式--简单介绍和使用

    装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象. 比如游戏机有一个GamePad类, 现在要增加一个作弊功能(例如100 ...

  9. Hibernate

  10. Android开发-之第一个程序:HelloWorld!

    小编觉得不管学习什么编程的时候,第一个程序都是要求打印输出一个"HelloWorld!",那就从最简单的HelloWorld开始吧!哈哈~~~~ 一.创建一个Android工程 1 ...