How to prevent Multiple Toast Overlaps

I've been using a common "myToast" which I use "myToast.cancel() prior to issuing a new toast. For Android v2.3 and older, this works great. When a new toast needs to be sent, the old one, if still on-screen, is canceled (and disappears immediately) to be replaced with the new toast. This avoids stacking up a bunch of toasts if the user presses a key multiple times that needs the alert (and other conditions). My actual case is one toast appears when a wrong key is pressed, and another appears if the Clear key is not pressed.

For Android 4.0 and 4.1, issuing a myToast.cancel() before the next toast kills both the current and the next toast. The current cancel() API does indicate it cancels the current AND the next toast (which seems rather stupid). Why cancel a toast you want to put up?

Any ideas on making cancel work consistently across Android versions (and the way it works in v2.3 and older)?

I'll try some inelegant dual toast system with tracking for which toast is in use, but it seems such a pain work around this bad behavior in 4.x to get what works perfectly and logically in older Android versions.


Ok, I solved it, but it's not nearly as clean as I would have liked. I implemented a dual toast approach, where it alternates between two toasts. First we define the toasts for the activity prior to the OnCreate:

Toast toast0;
Toast toast1;
private static boolean lastToast0 = true;

In the OnCreate:

toast0 = new Toast(getApplicationContext());
toast0.cancel();
toast1 = new Toast(getApplicationContext());
toast1.cancel();

And finally, when I need to display the toast and cancel the prior toast at the same time I use something similar to:

if (lastToast0) {
    toast0.cancel();
    toast1.setDuration(Toast.LENGTH_LONG);
    toast1.setText("new message");
    toast1.show();
    lastToast0 = false;
} else {
    toast1.cancel();
    toast0.setDuration(Toast.LENGTH_LONG);
    toast0.setText("new message");
    toast0.show();
    lastToast0 = true;
}

If you need to just cancel an existing toast (before it times out) use:

toast0.cancel();
toast1.cancel();

Tested on Nexus 7 (4.1), Emulator 4.0, and several devices with Android 2.2, 2.3.


Instead of calling cancel(). Try resetting the text and call show(). This should cancel the last toast by itself

myToast.setText("wrong key")
myToast.show();

If you keep using the same myToast instead of creating one every time I guess they won't stack up.


Did nandeesh's solution not work for you? His solution would be cleaner than using two different toasts.

For example, (expanding on his/her answer) prior to onCreate we'd declare the toast:

private Toast myToast;

and in onCreate we'd have to initialize it using makeToast (otherwise we'd get an error):

myToast = Toast.makeText(getApplicationContext(), null, Toast.LENGTH_SHORT);

and whenever we want a toast to be shown we'd simply call:

myToast.setText("some text");
myToast.show();

and this would replace the previous toast properly.