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.
Starting from Android Build. VERSION_CODES#R, apps targeting API level Build. VERSION_CODES#R or higher that are in the background will not have custom toast views displayed. If you want to avoid Toast overlapping, you could save the time the last Toast was shown using System.
LENGTH_LONG. Show the view or text notification for a long period of time. int. LENGTH_SHORT. Show the view or text notification for a short period of time.
The Toast class contains two predefined constants you can use: Toast. LENGTH_SHORT and Toast. LENGTH_LONG .
The android docs specifically mention application context: "This method takes three parameters: the application Context, the text message, and the duration for the toast. It returns a properly initialized Toast object."
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With