如何取消Toast
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何取消Toast相关的知识,希望对你有一定的参考价值。
我遇到了一个关于Toast的问题假设我的Toast显示在程序的窗口中,当Dialog box出现的时候,它不能立即消失,请问如何取消Toast.
参考技术A Toast默认显示时间参数有两种,0是比较短的,1是比较长的,如果要代码控制消失,直接调用Toast的cancel()就可以了,这个方法是说如果Toast还在显示就关闭Toast,你试试查看原帖>>
如果已经显示了一个 Toast,如何避免 Toast
【中文标题】如果已经显示了一个 Toast,如何避免 Toast【英文标题】:How to avoid a Toast if there's one Toast already being shown 【发布时间】:2011-10-19 00:05:03 【问题描述】:我有几个SeekBar
和onSeekBarProgressStop()
,我想显示一个Toast
消息。
但如果在SeekBar
上我快速执行操作,那么 UI 线程会以某种方式阻塞,Toast
消息会等待直到 UI 线程空闲。
现在我担心的是,如果 Toast
消息已经显示,则要避免新的 Toast
消息。或者他们是我们检查 UI 线程当前空闲的任何条件,然后我将显示 Toast
消息。
我尝试了两种方式,使用runOnUIThread()
并创建新的Handler
。
【问题讨论】:
【参考方案1】:我已经尝试了很多方法来做到这一点。起初我尝试使用cancel()
,但对我没有效果(另请参阅this answer)。
setDuration(n)
我也不会去任何地方。通过记录 getDuration()
发现它的值为 0(如果 makeText()
的参数是 Toast.LENGTH_SHORT
)或 1(如果 makeText()
的参数是 Toast.LENGTH_LONG
)。
最后我尝试检查吐司的视图isShown()
。当然,如果没有显示 toast 则不是,但更重要的是,在这种情况下它会返回一个致命错误。所以我需要尝试捕捉错误。
现在,如果显示 toast,isShown()
返回 true。
利用isShown()
我想出了方法:
/**
* <strong>public void showAToast (String st)</strong></br>
* this little method displays a toast on the screen.</br>
* it checks if a toast is currently visible</br>
* if so </br>
* ... it "sets" the new text</br>
* else</br>
* ... it "makes" the new text</br>
* and "shows" either or
* @param st the string to be toasted
*/
public void showAToast (String st) //"Toast toast" is declared in the class
try toast.getView().isShown(); // true if visible
toast.setText(st);
catch (Exception e) // invisible if exception
toast = Toast.makeText(theContext, st, toastDuration);
toast.show(); //finally display it
【讨论】:
好答案。一句话: isShown() “引发异常”的原因是 toast.getView() 最初返回null。简单地测试 null 而不是使用 try...catch。 您可以考虑直接检查而不是尝试/捕获,因为这是预期的常见情况。 查看我的回答 (***.com/a/29573861/2457744),了解如何在不尝试/捕获的情况下进行操作。 当我使用 Toast.LENGTH_SHORT 时它不工作,使用 Toast.LENGTH_LONG 工作正常后。 Toast.getView() 在 Android 11+ (***.com/questions/62884286/…) 上总是返回 null,所以这个解决方案已经过时了【参考方案2】:记录您上次展示 toast 的时间,如果它在某个时间间隔内,则重新展示它。
public class RepeatSafeToast
private static final int DURATION = 4000;
private static final Map<Object, Long> lastShown = new HashMap<Object, Long>();
private static boolean isRecent(Object obj)
Long last = lastShown.get(obj);
if (last == null)
return false;
long now = System.currentTimeMillis();
if (last + DURATION < now)
return false;
return true;
public static synchronized void show(Context context, int resId)
if (isRecent(resId))
return;
Toast.makeText(context, resId, Toast.LENGTH_LONG).show();
lastShown.put(resId, System.currentTimeMillis());
public static synchronized void show(Context context, String msg)
if (isRecent(msg))
return;
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
lastShown.put(msg, System.currentTimeMillis());
然后,
RepeatSafeToast.show(this, "Hello, toast.");
RepeatSafeToast.show(this, "Hello, toast."); // won't be shown
RepeatSafeToast.show(this, "Hello, toast."); // won't be shown
RepeatSafeToast.show(this, "Hello, toast."); // won't be shown
这并不完美,因为 LENGTH_SHORT
和 LENGTH_LONG
的长度未定义,但在实践中效果很好。与其他解决方案相比,它的优势在于您不需要保留 Toast 对象,并且调用语法保持简洁。
【讨论】:
很好,正是我想要的。效果很好。 也许是个好主意,但没有完美实现。您将对象放入 HashMap 中,但不删除它们。 由于键是要烘烤的字符串,因此映射的大小受要烘烤的字符串数量的限制。仅当您正在烘烤动态字符串(“foo bar”+ i)时,您的观点才有效。如果您需要更好的,请将 HashMap 替换为 LruCache。【参考方案3】:以下是most popular answer 的替代解决方案,不带try/catch。
public void showAToast (String message)
if (mToast != null)
mToast.cancel();
mToast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
mToast.show();
【讨论】:
最好的,谢谢!【参考方案4】:适用于停止堆叠,例如点击驱动吐司。基于@Addi 的回答。
public Toast toast = null;
//....
public void favsDisplay(MenuItem item)
if(toast == null) // first time around
Context context = getApplicationContext();
CharSequence text = "Some text...";
int duration = Toast.LENGTH_SHORT;
toast = Toast.makeText(context, text, duration);
try
if(toast.getView().isShown() == false) // if false not showing anymore, then show it
toast.show();
catch (Exception e)
【讨论】:
【参考方案5】:上述线程的增强功能,仅当与相同的文本消息不可见时才会显示吐司:
public void showSingleToast()
try
if(!toast.getView().isShown())
toast.show();
catch (Exception exception)
exception.printStackTrace();
Log.d(TAG,"Toast Exception is "+exception.getLocalizedMessage());
toast = Toast.makeText(this.getActivity(), getContext().getString(R.string.no_search_result_fou`enter code here`nd), Toast.LENGTH_SHORT);
toast.show();
【讨论】:
【参考方案6】:综合解决方案
就我而言,如果显示当前的 toast,我需要取消它并显示另一个。
这是为了解决当用户在服务仍在加载或不可用时请求服务的情况,我需要展示一个 toast(如果请求的服务不同,我可能会有所不同)。否则,toast 会一直按顺序显示,并且需要很长时间才能自动隐藏。
所以基本上我保存了正在创建的 toast 的实例,下面的代码是如何安全地取消它
synchronized public void cancel()
if(toast == null)
Log.d(TAG, "cancel: toast is null (occurs first time only)" );
return;
final View view = toast.getView();
if(view == null)
Log.d(TAG, "cancel: view is null");
return;
if (view.isShown())
toast.cancel();
else
Log.d(TAG, "cancel: view is already dismissed");
为了使用它,我现在不用担心取消,如下所示:
if (toastSingleton != null )
toastSingleton.cancel();
toastSingleton.showToast(messageText);
else
Log.e(TAG, "setMessageText: toastSingleton is null");
showToast 由您决定如何实现它,因为我需要自定义的 toast 外观。
【讨论】:
真实逻辑和真实检查空视图,然后再检查是否显示。多次调用显示祝酒词是一种很长很奇怪的体验,尤其是在用户已经退出应用程序的情况下。如您所述,必须取消当前然后调用新的。谢谢。【参考方案7】:开箱即用的干净解决方案。在你的 Activity 上定义这个:
private Toast toast;
/**
* Use this to prevent multiple Toasts from spamming the UI for a long time.
*/
public void showToast(CharSequence text, int duration)
if (toast == null)
toast = Toast.makeText(this, text, duration);
else
toast.setText(text);
toast.show();
public void showToast(int resId, int duration)
showToast(getResources().getText(resId), duration);
【讨论】:
【参考方案8】:检查是否在屏幕上显示 toast 消息,无论它是否显示。 用于显示 toast 消息创建一个单独的类。并使用此类在检查 toast 消息的可见性后显示 toast 消息的方法。使用这段代码:
public class AppToast
private static Toast toast;
public static void showToast(Context context, String message)
try
if (!toast.getView().isShown())
toast=Toast.makeText(context, message, Toast.LENGTH_SHORT);
toast.show();
catch (Exception ex)
toast=Toast.makeText(context,message,Toast.LENGTH_SHORT);
toast.show();
我希望这个解决方案对你有所帮助。
谢谢
【讨论】:
【参考方案9】:添加了 2 秒后移除吐司的计时器。
private Toast toast;
public void showToast(String text)
try
toast.getView().isShown();
toast.setText(text);
catch (Exception e)
toast = Toast.makeText(mContext, text, Toast.LENGTH_SHORT);
if(toast.getView().isShown())
new Timer().schedule(new TimerTask()
@Override
public void run()
toast.cancel();
, 2000);
else
toast.show();
showToast("Please wait");
【讨论】:
【参考方案10】:我的解决办法是:
public class Utils
public static Toast showToast(Context context, Toast toast, String str)
if (toast != null)
toast.cancel();
Toast t = Toast.makeText(context, str, Toast.LENGTH_SHORT);
t.show();
return t;
并且调用者应该有这个方法参数的 Toast 成员,或者
class EasyToast
Toast toast;
Context context;
public EasyToast(Context context)
this.context = context;
public Toast show(String str)
if (toast != null)
toast.cancel();
Toast t = Toast.makeText(context, str, Toast.LENGTH_SHORT);
t.show();
return t;
有一个这样的辅助类。
【讨论】:
我找到了同样的解决方案。如果 isShown() 没有按预期工作,那么就不要使用它:) 如果它不为空,则取消() toast。以上是关于如何取消Toast的主要内容,如果未能解决你的问题,请参考以下文章