`
cheng330301560
  • 浏览: 178800 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Toast显示和关闭自个控制的方法

阅读更多

 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 信息提示框的代码如下:
ITransientNotification  notification = (ITransientNotification) field.get(toast);
//  显示Toast信息提示框
notification.show();
//  关闭Toast信息提示框
notification.hide();

分享到:
评论
2 楼 fyc0109 2013-01-17  
小米测试无用。、
1 楼 lcsky 2013-01-16  
这个方法很有才!成功实践!但愿Android后续版本不要改Toast的实现~

相关推荐

    Android-AndroidToast即便关闭了通知权限也会正常显示

    在Android应用开发中,`Android Toast`是一种轻量级的提示机制,用于向用户显示简短的信息,通常在用户操作后出现并自动消失。...同时,自定义的`ToastUtils`工具类可以帮助开发者更好地管理和优化应用中的Toast显示。

    Android-屏蔽系统通知Toast无法显示的解决方案v2.0.0

    在Android开发过程中,有时我们...而"Android-屏蔽系统通知Toast无法显示的解决方案v2.0.0"提供了这样一个工具或方法,帮助开发者更好地应对这种场景。在使用时,需要根据项目的具体需求和兼容性要求进行选择和适配。

    c# winform 类似android toast消息功能

    7. **实际应用**:在你的主窗体中,当需要显示Toast时,调用封装好的静态方法,传入消息内容和显示时长。例如: ```csharp ToastMessage.Show("这是一个测试消息", 3000); ``` 通过以上步骤,你就能在C# WinForm...

    C# Winform 类似Android Toast消息功能

    4. **显示和隐藏逻辑**:编写代码控制Toast通知的显示和消失。可以设定一个显示时间,到达这个时间后自动隐藏。同时,提供手动关闭的选项,用户可以通过点击或按键关闭通知。 5. **事件处理**:添加必要的事件处理...

    android可设置任何时长可显示在任何位置的toast

    在创建完Toast后,可以设定一个延时消息,当延时结束后,调用Toast的`cancel()`方法来关闭它。 3. **设置显示位置** Android系统默认的Toast位置有限,但通过自定义可以实现更多可能性。关键在于获取屏幕尺寸,...

    Android开发技巧之永不关闭的Toast信息框(长时间显示而非系统关闭)

    那么有些时候需要这个Toast信息提示框长时间显示,直到需要关闭它时通过代码来控制,而不是让系统自动来关闭Toast信息提示框。不过这个要求对于Toast本身来说有些过分,因为Toast类并没有提供这个功能。虽然如此,但...

    重写仿toast

    在Android中,Toast是通过`Toast.makeText()`方法创建的,这个方法接收三个参数:上下文(Context)、显示的消息(String)和持续时间(int)。持续时间可以是`Toast.LENGTH_SHORT`或`Toast.LENGTH_LONG`。 重写仿...

    JQuery信息提示框插件 jquery.toast.js 的使用

    - `showClose`:是否显示关闭按钮,默认为 `true`。 - `onClick`:点击提示框时触发的回调函数。 - `onClose`:提示框关闭时触发的回调函数。 4. **关闭提示**:可以使用 `.toast('clear')` 来清除所有正在显示的...

    自定义Toast

    自定义Toast通常会在一段时间后自动消失,因此在创建Dialog时,可以使用`Handler`和`Runnable`来实现延时关闭的功能。 **示例代码(Kotlin):** ```kotlin class CustomToastFragment : AppCompatDialogFragment...

    Bootstrap toast消息框插件

    Bootstrap Toast消息框插件是基于流行的前端框架Bootstrap开发的一个组件,用于在网页上优雅地展示短暂的通知或消息。这些消息通常包含重要的信息、警告或成功提示,会在用户界面上短暂出现,然后自动消失,或者通过...

    bootstrap风格提示框直接可用toast

    Toast组件还提供了`shown.bs.toast`和`hidden.bs.toast`等事件,可以在Toast显示或隐藏时执行相应的回调函数,增强交互体验。 5. **自定义选项**: Bootstrap允许通过数据属性(data attributes)或JavaScript...

    iPhone上的Toast

    5. **显示和隐藏**:提供方法来显示和隐藏Toast,控制其生命周期,例如设置显示时长后自动消失。 6. **事件处理**:如果需要,可以添加手势识别器来响应用户的触摸事件,比如点击Toast关闭它。 7. **自定义**:提供...

    仿照安卓Toast 弹窗提示

    为了模仿Toast,我们需要创建一个新的UIView子类,定义它的外观和行为。这个子类可以包含文本标签(UILabel)来展示提示信息,以及设置宽高、坐标、颜色和展示时间等属性。 1. **创建自定义视图** 首先,创建一个...

    跳过小米和魅族手机对Toast的限制

    然而,一些国产手机厂商如小米和魅族,为了优化用户体验和控制系统的稳定性,可能会对系统级别的`Toast`显示进行限制或者定制化处理。这可能导致开发者在应用中调用`Toast`时无法正常显示,尤其是在用户关闭了系统...

    微信小程序Toast自定义组件

    4. **编写 JS 逻辑**:处理组件的显示和隐藏,可以使用 `wx.showModal` 或 `setTimeout` 控制显示时长,同时提供显示和关闭的方法供外部调用。 5. **配置 JSON 文件**:设置组件的对外属性,如显示文本、图标等,...

    基于Vuejs编写的Toast组件

    Toast组件就是这样一个自包含的单元,负责渲染和管理显示提示信息的功能。 2. **Vue实例和模板**:组件需要一个Vue实例来运行,通常在模板中定义HTML结构。模板中的指令(如`v-if`、`v-show`、`v-bind`等)会被Vue...

    Android中使用Toast.cancel()方法优化toast内容显示的解决方法

    总结来说,解决`Toast`内容堆积的问题,关键在于合理管理和控制`Toast`的生命周期,以及确保其更新和显示都在主线程进行。`Toast.cancel()` 在某些情况下可能不足以解决所有问题,因此需要结合其他技术手段,如使用`...

    移动H5领域。js、css3仿ios toast提示。

    7. **自定义配置**:为了提高代码的可复用性,我们可以设计一个`toast`函数,接受参数如文本内容、持续时间、是否显示关闭按钮等,以适应不同的使用场景。 综上所述,利用JavaScript和CSS3,开发者可以创建出高度...

    toast demo

    通过设置Gravity属性,可以改变Toast显示的位置。例如,我们可以让Toast显示在屏幕顶部,代码如下: ```java Toast toast = Toast.makeText(context, "自定义位置的Toast", Toast.LENGTH_SHORT); toast.setGravity...

    一个可以替代Toast的简单MessageView

    3. **显示时长控制**:与Toast不同,MessageView可以设置更精确的显示时间,或者让用户选择是否需要手动关闭。 4. **位置可调**:开发者可以自由设定MessageView在屏幕上的位置,而不仅仅是底部或中间。 5. **事件...

Global site tag (gtag.js) - Google Analytics