解决Toast的延时问题

http://blog.sina.com.cn/s/blog_76264a170100tfn7.html


Android的Toast是一个很常用的消息提示组件,开发的时候一般是用

            
Toast . makeText( context ,  text ,  duration ). show();
  
  来显示一条toast。这种方法有一个问题,如果一条旧消息没有消失以前,又产生了一条新消息,这时候新消息必须等待旧消息消失才能出现。然而实际情况中,我们通常更期望的表现是旧消息马上中止,新消息立刻出现。(不及时的通知不是好通知)
  那么怎样才能达到这种效果呢?
  Toast.makeText是一个静态工厂方法,每次调用这个方法都会产生一个新的Toast对象,在这个对象上调用show方法就会使这个对象加入到消息显示的队列里排队等候显示。实际上,如果我们不每次都产生一个新的toast对象,而是每一次都是用同一个,那么就不需要排队了,我们要的及时更新效果也就可以实现了。
  实际上,我们可以使用Toast本身的构造器产生一个新的Toast对象,并用setText和setDuration方法来达到和makeText同样的设置,之后也一样用show方法来显示。这样就把makeText方法产生对象和设置属性的操作分开来进行。也就是说,我们显示下一个toast的时候,可以不必再产生新对象,只要在原来的对象上重新设置属性,并重新show就可以了,这样新的toast就会代替原来的马上显示。
  代码大概是这样:

t  =  new  Toast( context);
t . setText( text);
t . setDuration( duration);
t . show();
t . setText( text_new);
t . setDuration( duration_new);
t . show();
  
  但实际上你会发现这个代码运行会报错,看看log就明白,说是必须调用setView方法。这个setView方法,是用来设置toast显示的view的,也就是说,我们可以让toast显示在自定义的view里,而不是那个统一的黑框里(除非特殊用途,一般不推荐,用户体验的统一是王道)。makeText这个方法是默认用那个统一黑框布局的(com.android.internal.R.layout.transient_notification),但通过构造器构造出来的toast必须自己手动设置setView。最要命的是默认的黑框布局在com.android.internal这个包里,而这个包在开发环境是访问不到的。
  这可怎么办呢?难道只能自定义一个view么?或者从android源码里把这个layout抓出来?前者毁坏了用户体验,后者也有问题,比如不同机器的移植layout是不同的。好在除了setView,toast还提供了一个对应的方法叫getView,我们可以通过makeText创建一个默认布局的toast然后通过getView拿到它的View的引用保存起来,以后每次产生toast的时候都使用这同一个View就好了。
  可以正常运行的代码如下:

t  =  new  Toast( context);
View  v  =  Toast . makeText( context ,  "" ,  Toast . LENGTH_SHORT ). getView();
t . setView( v);
t . setText( text);
t . setDuration( duration);
t . show();
t . setText( text_new);
t . setDuration( duration_new);
t . show();

  以上是概念代码,实际应用中,我们可以在应用的全局环境类里(通常是一个singleton)实现一个toast管理器的singleton,这样就确保所有的toast都通过这一个view来显示。至于toast管理器的单例实现,用一个enum就可以了,示例代码如下:

public  enum  toastMgr  {
        builder;

        private  View  v;
        private  Toast  it;
     
        private  void  init( Context  c{
                LayoutInflater  inflate  =( LayoutInflater) c . getSystemService( Context . LAYOUT_INFLATER_SERVICE);
                v  =  Toast . makeText( c ,  "" ,  Toast . LENGTH_SHORT ). getView();
                it  =  new  Toast( c);
                it . setView( v);
        }
             
        public  void  display( CharSequence  text ,  int  duration{
                it . setText( text);
                it . setDuration( duration);
                it . show();
        }

        public  void  display( int  Resid ,  int  duration{
                it . setText( Resid);
                it . setDuration( duration);
                it . show();
        }
       
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值