(读书笔记)Android Toast 显示时间叠加问题的探讨

在android中对于toast的显示一般有两种方法:

1
Toast.makeText(Context, int, int).show();

1
Toast.makeText(Context, CharSequence, int).show();

对于这两种方法第一个参数都是上下文(Context),第二个就是显示的内容,第三个是显示的时长,android给了我们时长的常量Toast.LENGTH_SHORT (2秒) Toast.LENGTH_LONG(3.5秒)
当你尝试在自定义时长时,如果设置得大于3500(ms)默认为LENGTH_LONG如果小于3500默认为LENGTH_SHORT所以,自定义时长都是心理安慰自己。什么?你不信?打开SDK文件夹查看下源码:在frameworks\base\services\java\com\android\server路径下有个NotificationManagerService.java的文件里面写到:

1
2
3
4
5
6
7
8
9
10
11
12
//这里定义了两个常量
private static final int LONG_DELAY = 3500; // 3.5 seconds
private static final int SHORT_DELAY = 2000; // 2 seconds
// 在下面的方法中调用要
private void scheduleTimeoutLocked(ToastRecord r, boolean immediate)
{
Message m = Message.obtain(mHandler, MESSAGE_TIMEOUT, r);
//三目运算符,要么是LONG_DELAY 要么是SHORT_DELAY所以只有这两种时间情况
long delay = immediate ? 0 : (r.duration == Toast.LENGTH_LONG ? LONG_DELAY : SHORT_DELAY);
mHandler.removeCallbacksAndMessages(r);
mHandler.sendMessageDelayed(m, delay);
}

这引发了一个问题,当我们同时显示多个toast时,就会出现时间的叠加问题,假设几乎同时显示3个设置为LENGTH_SHORT的toast那么就要耗时6秒显示完毕,而且用户体验特别不好,可能程序退出了,toast还没显示完成。那有什么方法可以解决这个时间叠加的问题呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

/**
* =============================================================================
* Copyright (c) 2016 yuxin All rights reserved.
* Packname com.jju.yuxin.dierzhou
* Created by yuxin.
* Created time 2016/9/12 0012 上午 11:00.
* Version 1.0;
* Describe : 不会出现时间叠加的Toast
* History:
* ==============================================================================
*/
public class ToastUtils {
private static Toast toast = null;

/**
* 判断toast是否存在,如果存在则更新text,达到避免出现时间叠加的问题
* @param context 上下文
* @param text 显示的内容
* @param duration 显示时长,默认值为Toast.LENGTH_SHORT (2秒)或Toast.LENGTH_LONG(3.5秒)
*/
public static void toastShow(Context context, String text, int duration) {
if (toast == null) {
toast = Toast.makeText(context, text, duration);
} else {
toast.setText(text);
}
toast.show();
}

/**
* 判断toast是否存在,如果存在则更新text,达到避免出现时间叠加的问题
* @param context 上下文
* @param resId 字符串资源文件ID
* @param duration 显示时长,默认值为Toast.LENGTH_SHORT (2秒)或Toast.LENGTH_LONG(3.5秒)
*/
public static void toastShow(Context context, int resId, int duration)
throws Resources.NotFoundException {
if (toast == null) {
toast = Toast.makeText(context, context.getResources().getText(resId), duration);
} else {
toast.setText(context.getResources().getText(resId));
}
toast.show();
}
}

自己编写一个toast工具文件,尽可能保持原方法的传参类型,至于show()这个容易让人忘记的方法我们就在里面默认调用了,避免忘记!
代码中其中关键的就是 toast.setText()这个方法,我们看下官方文档怎么介绍这个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* Update the text in a Toast that was previously created using one of the makeText() methods.
* @param s The new text for the Toast.
*/
public void setText(CharSequence s) {
if (mNextView == null) {
throw new RuntimeException("This Toast was not created with Toast.makeText()");
}
TextView tv = (TextView) mNextView.findViewById(com.android.internal.R.id.message);
if (tv == null) {
throw new RuntimeException("This Toast was not created with Toast.makeText()");
}
tv.setText(s);
}

利用已经创建的toast方法更新内容,这样就可以达到避免toast时间叠加的问题,只有最后一个toast才会完整的显示完指定时长。

参考博文:http://blog.csdn.net/zjbpku/article/details/7930764

我的博客网站:http://huyuxin.top/欢迎大家访问!评论!

您的一份奖励,就是我的一份激励