Android cancels Toast when exiting the application and when a toast is displayed

I read about this problem, but the answers do not seem to work.

I show Toast when the user clicks a button. When the user constantly presses the button, the toast continues to be displayed again and again, even when the user leaves this operation.

The length of the toast is short. The length of the toast cannot be changed because the text is long.

This is what I have tried so far:

  Toast toast; toast=Toast.makeText(getApplicationContext(),"text",Toast.LENGTH_SHORT); if(toast.getView().isShown()==false){ toast.show(); } 

This did not work.

I tried:

  if(toast.getView().isShown()==true){ toast.cancel(); } 

in onStop() . For some reason, the undo method never works.

If I put .cancel() before I show the application ... then there will be another zero check for this. But after that, that didn't work either. I can show a dialog instead of a toast, but that won't be the solution.

Is there a way to check if a toast is displayed or not?

For reference

  • Toast Message on Android

  • Avoiding a toast if you already have one toast

  • How to prevent multiple toast overflows

  • Cancel an already open toast in Android

+8
android toast
Apr 19 '13 at 5:57 on
source share
4 answers

The trick is to keep track of the last Toast that has been shown and undo it.

What I did was create a Toast wrapper containing a static link to the last displayed toast.

When I need to show a new one, I first canceled the static link before showing the new one (and saved it in the static).

Here's the full Boast wrapper code I created - it mimics Toast methods so I can use them. By default, Boast will override the previous one, so you will not create a queue of pending Toasts.

This code can be found in my Github gist:

If you just want to learn how to cancel notifications when you exit the application, you will find a lot of help there. If you have any improvements or suggestions, please feel free to unblock them and contact us. This is a very old answer, but the code has been stable in production on several applications for some time.

BTW - In most cases, this should be a direct replacement for Toast .




 package mobi.glowworm.lib.ui.widget; import android.annotation.SuppressLint; import android.content.Context; import android.content.res.Resources; import android.support.annotation.Nullable; import android.widget.Toast; import java.lang.ref.WeakReference; /** * {@link Toast} decorator allowing for easy cancellation of notifications. Use this class if you * want subsequent Toast notifications to overwrite current ones. </p> * <p/> * By default, a current {@link Boast} notification will be cancelled by a subsequent notification. * This default behaviour can be changed by calling certain methods like {@link #show(boolean)}. */ public class Boast { /** * Keeps track of certain Boast notifications that may need to be cancelled. This functionality * is only offered by some of the methods in this class. * <p> * Uses a {@link WeakReference} to avoid leaking the activity context used to show the original {@link Toast}. */ @Nullable private volatile static WeakReference<Boast> weakBoast = null; @Nullable private static Boast getGlobalBoast() { if (weakBoast == null) { return null; } return weakBoast.get(); } private static void setGlobalBoast(@Nullable Boast globalBoast) { Boast.weakBoast = new WeakReference<>(globalBoast); } // //////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Internal reference to the {@link Toast} object that will be displayed. */ private Toast internalToast; // //////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Private constructor creates a new {@link Boast} from a given {@link Toast}. * * @throws NullPointerException if the parameter is <code>null</code>. */ private Boast(Toast toast) { // null check if (toast == null) { throw new NullPointerException("Boast.Boast(Toast) requires a non-null parameter."); } internalToast = toast; } // //////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Make a standard {@link Boast} that just contains a text view. * * @param context The context to use. Usually your {@link android.app.Application} or * {@link android.app.Activity} object. * @param text The text to show. Can be formatted text. * @param duration How long to display the message. Either {@link Toast#LENGTH_SHORT} or * {@link Toast#LENGTH_LONG} */ @SuppressLint("ShowToast") public static Boast makeText(Context context, CharSequence text, int duration) { return new Boast(Toast.makeText(context, text, duration)); } /** * Make a standard {@link Boast} that just contains a text view with the text from a resource. * * @param context The context to use. Usually your {@link android.app.Application} or * {@link android.app.Activity} object. * @param resId The resource id of the string resource to use. Can be formatted text. * @param duration How long to display the message. Either {@link Toast#LENGTH_SHORT} or * {@link Toast#LENGTH_LONG} * @throws Resources.NotFoundException if the resource can't be found. */ @SuppressLint("ShowToast") public static Boast makeText(Context context, int resId, int duration) throws Resources.NotFoundException { return new Boast(Toast.makeText(context, resId, duration)); } /** * Make a standard {@link Boast} that just contains a text view. Duration defaults to * {@link Toast#LENGTH_SHORT}. * * @param context The context to use. Usually your {@link android.app.Application} or * {@link android.app.Activity} object. * @param text The text to show. Can be formatted text. */ @SuppressLint("ShowToast") public static Boast makeText(Context context, CharSequence text) { return new Boast(Toast.makeText(context, text, Toast.LENGTH_SHORT)); } /** * Make a standard {@link Boast} that just contains a text view with the text from a resource. * Duration defaults to {@link Toast#LENGTH_SHORT}. * * @param context The context to use. Usually your {@link android.app.Application} or * {@link android.app.Activity} object. * @param resId The resource id of the string resource to use. Can be formatted text. * @throws Resources.NotFoundException if the resource can't be found. */ @SuppressLint("ShowToast") public static Boast makeText(Context context, int resId) throws Resources.NotFoundException { return new Boast(Toast.makeText(context, resId, Toast.LENGTH_SHORT)); } // //////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Show a standard {@link Boast} that just contains a text view. * * @param context The context to use. Usually your {@link android.app.Application} or * {@link android.app.Activity} object. * @param text The text to show. Can be formatted text. * @param duration How long to display the message. Either {@link Toast#LENGTH_SHORT} or * {@link Toast#LENGTH_LONG} */ public static void showText(Context context, CharSequence text, int duration) { Boast.makeText(context, text, duration).show(); } /** * Show a standard {@link Boast} that just contains a text view with the text from a resource. * * @param context The context to use. Usually your {@link android.app.Application} or * {@link android.app.Activity} object. * @param resId The resource id of the string resource to use. Can be formatted text. * @param duration How long to display the message. Either {@link Toast#LENGTH_SHORT} or * {@link Toast#LENGTH_LONG} * @throws Resources.NotFoundException if the resource can't be found. */ public static void showText(Context context, int resId, int duration) throws Resources.NotFoundException { Boast.makeText(context, resId, duration).show(); } /** * Show a standard {@link Boast} that just contains a text view. Duration defaults to * {@link Toast#LENGTH_SHORT}. * * @param context The context to use. Usually your {@link android.app.Application} or * {@link android.app.Activity} object. * @param text The text to show. Can be formatted text. */ public static void showText(Context context, CharSequence text) { Boast.makeText(context, text, Toast.LENGTH_SHORT).show(); } /** * Show a standard {@link Boast} that just contains a text view with the text from a resource. * Duration defaults to {@link Toast#LENGTH_SHORT}. * * @param context The context to use. Usually your {@link android.app.Application} or * {@link android.app.Activity} object. * @param resId The resource id of the string resource to use. Can be formatted text. * @throws Resources.NotFoundException if the resource can't be found. */ public static void showText(Context context, int resId) throws Resources.NotFoundException { Boast.makeText(context, resId, Toast.LENGTH_SHORT).show(); } // //////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Close the view if it showing, or don't show it if it isn't showing yet. You do not normally * have to call this. Normally view will disappear on its own after the appropriate duration. */ public void cancel() { internalToast.cancel(); } /** * Show the view for the specified duration. By default, this method cancels any current * notification to immediately display the new one. For conventional {@link Toast#show()} * queueing behaviour, use method {@link #show(boolean)}. * * @see #show(boolean) */ public void show() { show(true); } /** * Show the view for the specified duration. This method can be used to cancel the current * notification, or to queue up notifications. * * @param cancelCurrent <code>true</code> to cancel any current notification and replace it with this new * one * @see #show() */ public void show(boolean cancelCurrent) { // cancel current if (cancelCurrent) { final Boast cachedGlobalBoast = getGlobalBoast(); if ((cachedGlobalBoast != null)) { cachedGlobalBoast.cancel(); } } // save an instance of this current notification setGlobalBoast(this); internalToast.show(); } } 
+12
Apr 19 '13 at 7:57
source share

Instead of canceling the toast. change the text. For example

  Toast t; t = Toast.makeText(this, "hi", 3000); t.show(); 

when you need another toast, use

  t.setText("bye"); t.show(); 

And if you want to reject the toast, just call t.cancel()

+3
Apr 19 '13 at 6:07
source share

You can cancel individual toasts by calling cancel () on the Toast object. AFAIK, you cannot cancel all outstanding toasts.

+1
Apr 19 '13 at 6:03
source share

Try to keep the time stamp of the last toast and do not allow new toasts until the expiration of the waiting period.

Something like:

 private static final long TOAST_TIMEOUT_MS = 2000; // tweak this constant private static long lastToastTime = 0; public void onButtonClicked() { long now = System.currentTimeMillis(); if (lastToastTime + TOAST_TIMEOUT_MS < now) { Toast.makeText(...).show(); lastToastTime = now; } } 

I would not worry that one toast sticking out for a second after the user exits the application is pretty standard behavior.

-one
Apr 19 '13 at 6:04 on
source share



All Articles