发一些《Android开发权威指南》的章节给大家尝尝鲜
Toast信息提示框之所以在显示一定时间后会自动关闭,是因为在系统中有一个Toast队列。系统会依次从队列中取(出队列)一个Toast,并显示它。在显示一段时间后,再关闭,然后再显示下一个Toast信息提示框。直到Toast队列中所有Toast都显示完为止。那么有些时候需要这个Toast信息提示框长时间显示,直到需要关闭它时通过代码来控制,而不是让系统自动来关闭Toast信息提示框。不过这个要求对于Toast本身来说有些过分,因为Toast类并没有提供这个功能。虽然如此,但方法总比问题多。通过一些特殊的处理还是可以实现这个功能的,而且并不复杂。
从7.3.1节的内容可以知道,Toast信息提示框需要调用Toast.show方法来显示。下面来看一下show方法的源代码。
public void show() {
if (mNextView == null) {
throw new RuntimeException("setView must have been called");
}
INotificationManager service = getService();
String pkg = mContext.getPackageName();
TN tn = mTN;
try {
//将当前Toast加入到Toast队列
service.enqueueToast(pkg, tn, mDuration);
} catch (RemoteException e) {
// Empty
}
}
show方法的代码并不复杂,可以很容易找到如下的代码。
service.enqueueToast(pkg, tn, mDuration);
从上面的代码可以很容易推断出它的功能是将当前的Toast加入到系统的Toast队列中。看到这里,各位读者应该想到。虽然show方法的表面功能是显示Toast信息提示框,但其实际的功能是将Toast加入到队列中,再由系统根据Toast队列来显示Toast信息提示框。那么我们经过更进一步地思考,可以大胆地做出一个初步的方案。既然系统的Toast队列可以显示Toast信息提示框,那么我们为什么不可以自己来显示它呢?这样不是可以自己来控制Toast的信息提示框的显示和关闭了吗!当然,这就不能再调用show方法来显示Toast信息提示框了(因为show方法会将Toast加入队列,这样我们就控制不了Toast了)。
既然初步方案已拟定,现在就来实施它。先在Toast类找一下还有没有其他的show方法。结果发现了一个TN类,该类是Toast的一个内嵌类。在TN类中有一个show方法。TN是ITransientNotification.Stub的子类。从ITransientNotification和TN类中的show方法初步推断(因为Transient的中文意思是“短暂的”)系统是从Toast队列中获得了Toast对象后,利用TN对象的show方法显示Toast,再利用TN.hide方法来关闭Toast。首先声明,这只是假设,我们还不知道这么做是否可行!当然,这也是科学研究的一般方法,先推断或假设,然后再证明推断或假设。
现在关键的一步是获得TN对象。遗憾的是TN被声明成private类型,外部无法访问。不过别着急。在Toast类中有一个mTN变量。虽然不是public变量,但仍然可以通过反射技术访问该变量。mTN变量会在创建Toast对象时初始化。因此,只要获得mTN变量,就获得了TN对象。下面的代码显示了一个永远不会自动关闭的Toast信息提示框。
//先创建一个Toast对象
Toast toast = Toast.makeText(this, "永不消失的Toast", Toast.LENGTH_SHORT);
//设置Toast信息提示框显示的位置(在屏幕顶部水平居中显示)
toast.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 0);
try
{
//从Toast对象中获得mTN变量
Field field = toast.getClass().getDeclaredField("mTN");
field.setAccessible(true);
Object obj = field.get(toast);
//TN对象中获得了show方法
Method method =obj.getClass().getDeclaredMethod("show", null);
//调用show方法来显示Toast信息提示框
method.invoke(obj, null);
}
catch (Exception e)
{
}
上面的代码中try{…}catch(…){…}语句中的代码是关键。先利用事先创建好的Toast对象获得了mTN变量。然后再利用反射技术获得了TN对象的show方法。
关闭Toast和显示Toast的方法类似,只是需要获得hide方法,代码如下:
try
{
//需要将前面代码中的obj变量变成类变量。这样在多个地方就都可以访问了
Method method =obj.getClass().getDeclaredMethod("hide", null);
method.invoke(obj, null);
}
catch (Exception e)
{
}
上面的代码已经很完美地实现了通过代码控制Toast信息提示框显示和关闭的功能。但如果想实现得更完美,可以在Android SDK源代码中找一个叫ITransientNotification.aidl的文件(该文件是AIDL服务定义文件,将在后面详细介绍),并在Android工程的src目录中建一个android.app包,将这个文件放到这个包中。然后ADT会自动在gen目录中生成了一个android.app包,包中有一个ITransientNotification.java文件。由于Android
SDK自带的ItransientNotification接口属于内部资源,外部程序无法访问,因此,只能将从Toast对象中获得的mTN变量转换成刚才生成的ITransientNotification对象了。这样就不需要使反射技术获得show和hide方法了。经过改良的显示和关闭Toast信息提示框的代码如下:
ITransientNotificationnotification = (ITransientNotification) field.get(toast);
//显示Toast信息提示框
notification.show();
//关闭Toast信息提示框
notification.hide();
分享到:
相关推荐
嵌入式Android项目设计与开发 第二章 Android调试基础 —— Log和Toast 调试手段 主要内容: 1.介绍消息日志的打印 2.Toast提示框的基本使用方法 调试手段 android.util.Log常用的方法有以下5个:Log.v() Log.d() ...
Toast信息提示框之所以在显示一定时间后会自动关闭,是因为在系统中有一个Toast队列。系统会依次从队列中取(出队列)一个Toast,并显示它。在显示一段时间后,再关闭,然后再显示下一个Toast信息提示框。直到Toast...
详细可参考博文:原创 android内存泄露:3、Handler的错误使用导致内存泄露 ,这篇文章我们将介绍:Toast的错误使用导致内存泄露 二、Toast的错误使用导致内存泄露 我们通常,连续点击按钮多次提示的 Toast,它...
常常开发都需要用到Toast提示框 可以优化系统自带的Toast提示框
一个简单的自定义Toast资源,您可以根据自己的需要更改我的代码即可实现您想要的效果(主要是更改xml文件的布局),这是androidstudio的项目,但是不妨碍在eclipse中使用,可以直接在eclipse中新建android项目,然后将...
全局Toast工具类,作用:连续显示toast提示时取消上一个toast 通过ToastUtil.toast(Context(), "文本")调用
React Native Toast 一个用于android和ios类似于android toast提示控件,android使用原生toast, ios使用UIView Toast
Android Toast 自定义背景、图片 随心使用
主要完成3中形式的Toast: 1、标准形式 2、设置位置形式 3、带图片的Toast
Android学习笔记之Button,Toast,menu的简单用法
Android 统一管理项目中的Toast弹出框,这样项目中的弹出框就不会重复
最近在开发中我们经常会在适配5.0以后的机型遇到各种各样的问题,其中有一个不大不小的问题就是:Toast不显示问题,这篇文章就给大家总结了Android 5.0以上Toast不显示的原因与解决方法,有需要的朋友们可以参考借鉴...
博客地址:已投入公司项目多时,没有任何毛病,可胜任任何需求,想了解实现原理的可以点击此链接查看: 源码本框架意在解决一些常见需求,如果是有一些极端的需求推荐使用集成步骤dependencies { implementation '...
android Toast对象的使用 自定义Toast
而toast是没有焦点的,时间到了自动消失,不能回应用户的交互,下面就跟大家分享下Android中Toast提示框的优化方法。 先看下源码: public class Toast { public static final int LENGTH_SHORT = 0; public ...
android组件 RadioButton,CheckBox,Toast简单介绍,
vue 类似安卓 IOS的toast 提示框 比如 登录成功后就可以使用
html5制作仿安卓android app的toast提示框
FrenchToast ...The API is error prone: Toast.makeText(context, "Important Toast", LENGTH_LONG); // Don't forget show()! FrenchToast gives you absolute control over your app Toasts. It