- 浏览: 24472 次
- 性别:
- 来自: 深圳
最新评论
Android中Toast的显示时间为特定时间且不可更改,但是有时候我们开发设计需要让Toast显示更长时间,或者自己完全控制Toast的显示和关闭。通过查看Toast类的源码,可以看出,这有点难为它了,Toast类本身并没有提供相应方法。
但是通过源码的查看,还是可以看出点眉头。源码分析思路在这里转eoe里的一篇文章,思路较为清晰:
转:
Toast信息提示框之所以在显示一定时间后会自动关闭,是因为在系统中有一个Toast队列。系统会依次从队列中取(出队列)一个Toast,并 显示它。在显示一段时间后,再关闭,然后再显示下一个Toast信息提示框。直到Toast队列中所有Toast都显示完为止。那么有些时候需要这个Toas t信息提示框长时间显示,直到需要关闭它时通过代码来控制,而不是让系统自动来关闭Toast信息提示框。不过这个要求对于Toast本身来说有些过 分,因为Toast类并没有提供这个功能。虽然如此,但方法总比问题多。通过一些特殊的处理还是可以实现这个功能的,而且并不复杂。
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信息提示框的代码如下:
ITransientNotification notification = (ITransientNotification) field.get(toast);
// 显示Toast信息提示框
notification.show();
// 关闭Toast信息提示框
notification.hide();
最后整理代码如下:
转载http://blog.csdn.net/sunshine0592/article/details/7010778
但是通过源码的查看,还是可以看出点眉头。源码分析思路在这里转eoe里的一篇文章,思路较为清晰:
转:
Toast信息提示框之所以在显示一定时间后会自动关闭,是因为在系统中有一个Toast队列。系统会依次从队列中取(出队列)一个Toast,并 显示它。在显示一段时间后,再关闭,然后再显示下一个Toast信息提示框。直到Toast队列中所有Toast都显示完为止。那么有些时候需要这个Toas t信息提示框长时间显示,直到需要关闭它时通过代码来控制,而不是让系统自动来关闭Toast信息提示框。不过这个要求对于Toast本身来说有些过 分,因为Toast类并没有提供这个功能。虽然如此,但方法总比问题多。通过一些特殊的处理还是可以实现这个功能的,而且并不复杂。
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信息提示框的代码如下:
ITransientNotification notification = (ITransientNotification) field.get(toast);
// 显示Toast信息提示框
notification.show();
// 关闭Toast信息提示框
notification.hide();
最后整理代码如下:
import java.lang.reflect.Field; import java.lang.reflect.Method; import android.app.Activity; import android.os.Bundle; import android.view.Gravity; import android.view.View; import android.widget.Button; import android.widget.Toast; public class TestToastActivity extends Activity { private Button showtoast,closetoast; private Toast toast; private Field field; private Object obj; private Method showMethod,hideMethod; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //初始化按钮组件 showtoast = (Button)this.findViewById(R.id.showtoast); closetoast = (Button)this.findViewById(R.id.closetoast); //设置组件监听 showtoast.setOnClickListener(new MyOnClickListener()); closetoast.setOnClickListener(new MyOnClickListener()); //创建Toast对象 toast = Toast.makeText(this, "Toast自定义显示时间测试", 1); toast.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL, 0, 0); //利用反射技术拿到mTN对象 reflectionTN(); } class MyOnClickListener implements View.OnClickListener{ @Override public void onClick(View v) { switch (v.getId()) { case R.id.showtoast: try { showMethod.invoke(obj, null);//调用TN对象的show()方法,显示toast } catch (Exception e) { e.printStackTrace(); } break; case R.id.closetoast: try { hideMethod.invoke(obj, null);//调用TN对象的hide()方法,关闭toast } catch (Exception e) { e.printStackTrace(); } break; default: break; } } } private void reflectionTN() { try { field = toast.getClass().getDeclaredField("mTN"); field.setAccessible(true); obj = field.get(toast); showMethod = obj.getClass().getDeclaredMethod("show", null); hideMethod = obj.getClass().getDeclaredMethod("hide", null); } catch (Exception e) { e.printStackTrace(); } } }
转载http://blog.csdn.net/sunshine0592/article/details/7010778
发表评论
-
ListView的优化
2012-07-13 17:20 9361. ListView需要设置adapter,它的item是通 ... -
Android修改system只读权限
2012-06-05 10:58 2578Android上替换Launcher有两种方法,一种是将img ... -
给Android应用开发者的十个建议 (转)
2012-05-30 10:14 919随着移动平台的发展和 ... -
Android推送机制
2012-05-29 14:35 3278关于服务器端向Android客户端的推送,主要有三种方式: ... -
Android Push Notification实现信息推送使用
2012-05-29 14:27 1165Apndroid Push Notification的 ... -
Android - proguard混淆器出错
2012-05-07 14:52 1916按照官方说明,在发布a ... -
AndroidManifest.xml中 andorid 版本号 versionCode, versionName
2012-04-04 23:45 2320但凡接触过ADV都知道 android 的app 有个 And ... -
android反编译----smali Wiki翻译--寄存器
2012-03-30 10:25 2181寄存器 Registers 描述smali文件中寄存器的具体信 ... -
Conversion to Dalvik format failed with error 1
2012-03-28 13:47 810最近发现公司换了新电脑后,在项目加入混淆之后,导出都会提示 ... -
setOnTouchEvent只能监听到ACTION_DOWN,监听不到ACTION_MOVE
2012-03-25 20:59 3464今天在做自定义的可选文本的 TextView 类时,用到了 V ...
相关推荐
Android 自定义 Toast 设定显示时间是指在 Android 应用程序中,自定义 Toast 的显示时间,而不是使用系统默认的 Toast.LENGTH_SHORT 或 Toast.LENGTH_LONG。本文将详细介绍如何使用 WindowManager 实现自定义 Toast...
本文将详细介绍如何在Android中实现`Toast`的自定义样式,包括自定义位置、添加图片以及自定义显示时长。 一、自定义`Toast`的位置 系统默认的`Toast`会在屏幕底部或中间显示,但这往往不能满足所有设计需求。我们...
在Android开发中,Toast是一种轻量级的通知方式,它用于显示短暂的信息,不会阻断用户当前的操作。默认的Toast在屏幕中央短暂显示文本信息,但有时开发者可能需要更灵活的展示方式,比如改变位置或样式,这就涉及到...
/* 显示toast,自己定义显示长短。 * param1:activity 传入context * param2:word 我们需要显示的toast的内容 * param3:time length long类型,我们传入的时间长度(如500)*/
在Android开发中,`Toast`是一个非常常用的组件,它用于在界面上显示短暂的通知信息,不会影响用户与屏幕上的其他元素交互。`Toast`对象的使用主要包括基本用法和自定义实现,下面将详细讲解这两个方面。 ### 基本...
Android 自定义 Toast 显示时间是 Android 开发中的一个重要知识点。Toast 是 Android 中的一种常见的提示信息,通常用于显示一些短暂的信息。但是,Android 的默认 Toast 显示时间是固定的,无法根据需要进行调整。...
一个简单的自定义Toast资源,您可以根据自己的需要更改我的代码即可实现您想要的效果(主要是更改xml文件的布局),这是androidstudio的项目,但是不妨碍在eclipse中使用,可以直接在eclipse中新建android项目,然后将...
Android中定义了一个Toast对象,用以弹出一个窗口来给予用户帮助和提示,和对话框不同的是,Toast并不是以独占方式显示的,它并不会抢夺用户的焦点,在弹出Toast的时候,依然可以对之前的界面进行操作,我们在“”...
在Android开发中,`Toast`是一种轻量级的提示方式,用于向用户显示短暂的信息,如操作结果或者简单的提示。通常,`Toast`会显示一个简单的文本消息,但默认样式可能无法满足所有设计需求。本篇文章将深入探讨如何在...
Android 源码演示5种toast显示效果,一共是以下几种演示:默认的Toast显示、自定义位置的Toast显示、带图片的Toast显示、完全自定义的Toast显示、长时间的Toast显示,Android 自定义5种toast显示效果。有的Toast效果...
系统默认的Toast显示时间有限,一般分为短时间和长时间两种模式,但有时开发者可能需要更灵活的控制Toast的显示时长,这就涉及到了自定义Toast。在本篇内容中,我们将深入探讨如何在Android中实现自定义时长的Toast...
在Android应用开发中,Toast是一种常用的轻量级提示方式,用于短暂显示消息,告知用户一些信息或者操作结果。然而,系统默认的Toast虽然方便,但其样式和功能相对固定,不能满足所有开发者的需求。在某些情况下,...
在Android开发中,自定义Dialog和Toast是提升用户体验和界面个性化的重要手段。Dialog通常用于向用户展示重要信息或需要用户做出决策的情况,而Toast则用于轻量级的通知,不打断用户的当前操作。以下是对如何自定义...
pc模拟Android端toast效果,自定义两种形式 详细参照此贴:https://blog.csdn.net/qq_37603131/article/details/124287143?spm=1001.2014.3001.5501
因此,自定义的Toast库应运而生,如“Android-Toaster”,它为开发者提供了更多的自定义选项,让提示信息更具特色。 **1. Android Toast的基本概念** Toast是Android系统提供的一种轻量级提示机制,用于显示短暂的...
在Android开发中,Toast是一种轻量级的通知方式,它能够在屏幕中央短暂地显示一行文本信息。然而,系统默认的Toast功能有限,仅提供简单的文本显示和预设的显示位置。当我们需要更复杂的交互或者定制化设计时,就...
在Android开发中,Toast是一种轻量级的通知方式,它能够在屏幕上的某一位置短暂显示信息,然后自动消失。然而,系统默认的Toast样式和位置可能无法满足所有应用的需求,因此开发者有时需要自定义Toast来实现更个性化...
本文将深入探讨如何在Android中自定义Toast,包括自定义显示时间和样式。 ### 一、自定义显示时间 系统默认的Toast显示时间分为短时间和长时间,但这些预设值可能并不符合特定场景的需求。要自定义显示时间,我们...
本文将详细介绍如何实现自定义Toast的位置、视图以及显示时间,并探讨如何隐藏Toast中的标题栏(虽然实际上Android默认的Toast并不包含标题栏)。 #### 二、自定义Toast的位置 在Android中,默认情况下,Toast会...
在Android开发中,`Toast`是一种常见的用于短暂显示简短信息的工具,它可以在屏幕上浮动一段时间后自动消失。默认情况下,`Toast`显示一个简单的文本消息,但有时我们需要自定义`Toast`的视图,以满足更复杂的需求,...