Android - Hide all shown Toast Messages
AndroidHideMessagesToastAndroid Problem Overview
How do I remove all toast messages currently displayed?
In my App, there is a list, when a user clicks on an item, a toast message is displayed, 10 items - 10 toast messages.
So if the user clicks 10 times, then presses the menu button, they have to wait for some seconds until they're able to read the menu option text.
It shouldn't be like that :)
Android Solutions
Solution 1 - Android
My solution was to initialize a single Toast in the activity. Then changing its text on each click.
Toast mToast = Toast.makeText(this, "", Toast.LENGTH_SHORT);
if (a) {
mToast.setText("This is a");
mToast.show();
} else if (b) {
mToast.setText("This is b");
mToast.show();
}
Solution 2 - Android
> how do I disable all toast messages > being process currently?
You can cancel individual Toasts
by calling cancel()
on the Toast
object. AFAIK, there is no way for you to cancel all outstanding Toasts
, though.
Solution 3 - Android
What about checking if a toast is already being displayed?
private Toast toast;
...
void showToast() {
if (toast == null || toast.getView().getWindowVisibility() != View.VISIBLE) {
toast = Toast.makeText(getActivity(), "Toast!", Toast.LENGTH_LONG);
toast.show();
}
}
Solution 4 - Android
Mudar's solution worked beautifully for me on a similar problem - I had various toasts stacking up in a backlog after multiple button
clicks.
One instance of Toast with different setText()s
and show()
s was the exactly the answer I was looking for - previous message cancelled as soon as a new button is clicked. Spot on
Just for reference, here's what I did...
In OnCreate
:
final Toast myToast = Toast.makeText(getBaseContext(), "", Toast.LENGTH_SHORT);
Within in each OnClick
:
myToast.setText(R.string.toast1);
myToast.show();
Solution 5 - Android
My solution is to save all toast references in a list and make a method to cancel all them when need it:
private ArrayList<Toast> msjsToast = new ArrayList<Toast>();
private void killAllToast(){
for(Toast t:msjsToast){
if(t!=null) {
t.cancel();
}
}
msjsToast.clear();
}
When you create a Toast do this way and save the reference:
Toast t = Toast.makeText(context, "Download error: xx", Toast.LENGTH_LONG);
t.show();
msjsToast.addToast(t);
When you need to delete them:
killAllToast();
You can create this like a static method in a global class and use it to kill all the toast of the app.
Solution 6 - Android
Here is my simple answer to the problem:
First in your activity create a global Toast
object.
private Toast example;
Now whenever you want to call a new Toast message just do this:
if(buttonClicked) {
example.cancel();
example = Toast.makeText(this, "" , Toast.LENGTH_SHORT);
example.setText("Button Clicked");
example.show();
}
This keeps all the Toasts in one central Toast and removes Toast spam. This is a quick rough solution so maybe there is a more elegant way to do it.
Solution 7 - Android
Kotlin Version
via Extension Function
• The best way to cancel previously shown Toast
and display a new one instantly is to keep a reference to the currently shown Toast
to be able to cancel it. So using these extension functions really helps:
ToastUtils.kt
import android.content.Context
import android.widget.Toast
import androidx.annotation.StringRes
/**
* @author aminography
*/
private var toast: Toast? = null
fun Context.toast(message: CharSequence?) {
toast?.cancel()
toast = message?.let { Toast.makeText(this, it, Toast.LENGTH_SHORT) }?.apply { show() }
}
fun Context.longToast(message: CharSequence?) {
toast?.cancel()
toast = message?.let { Toast.makeText(this, it, Toast.LENGTH_LONG) }?.apply { show() }
}
fun Context.toast(@StringRes message: Int) {
toast?.cancel()
toast = Toast.makeText(this, message, Toast.LENGTH_SHORT).apply { show() }
}
fun Context.longToast(@StringRes message: Int) {
toast?.cancel()
toast = Toast.makeText(this, message, Toast.LENGTH_LONG).apply { show() }
}
Usage:
context.toast("Text 1")
context.longToast("Text 2")
context.toast(R.string.text3)
context.longToast(R.string.text4)
Solution 8 - Android
I think I found a way to make toasts message not queue up for me. Thought I would share.
this part goes at top.
private Toast msg;
This part goes in my setOnTouchListener()
if(null == msg)
{
msg = Toast.makeText("Message to user!", Toast.LENGTH_SHORT);
msg.setGravity(Gravity.CENTER, msg.getXOffset() / 2, msg.getYOffset() / 2);
msg.show();
//handels the stupid queueing toast messages
new Handler().postDelayed(new Runnable()
{
public void run()
{
msg = null;
}
}, 2000);
}
It is more of a hack than anything. But I show a toast message any time someone favorites a part of my app. And if they go crazy clicking the favorite button it will go crazy with the toasts messages. But not anymore. It will wait 2 seconds and then set my toast object to null and allow it to display again.
Solution 9 - Android
Create a Toast object outside onClick
function and use the code below.
It will stop any existing Toast and start the latest Toast.
Toast mToast;
public void onClick(String abc) {
if(mToast!=null)
mToast.cancel();
Context context = this;
mToast = Toast.makeText(context, abc, Toast.LENGTH_SHORT);
mToast.show();
}
Solution 10 - Android
This is how I do it.
Toast toast;
if(toast==null)
toast=Toast.makeText(getApplicationContext(),R.string.act_now_private_post_text,Toast.LENGTH_LONG);
else
toast.setText(R.string.act_now_private_post_text);
toast.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL,10,10);
toast.show();
Solution 11 - Android
In Kotlin, it's an easy fix.
In my example, i toggle the sort type when the user clicks on a button. If the user rapidly clicks on the button, it will cancel the currently displayed sortToast
before another is shown.
private var sortToast: Toast? = null
sortButton.onClickListener {
sortToast?.cancel()
sortToast = Toast.makeText(context, "Sort by toggled", Toast.LENGTH_SHORT)
sortToast?.show()
}
Solution 12 - Android
mToast=Toast.makeText(this, "", Toast.LENGTH_LONG);
showToast.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mToast.cancel();
String text=null;
if(ON)
{
text="Toast is on";
}
else
{
text="Toast is off";
}
mToast.setText(text);
mToast.setDuration(Toast.LENGTH_SHORT);
mToast.show();
}
});
Solution 13 - Android
You can use like this..
class MyToast {
private static Toast t;
public MyToast(Context ctx, String message) {
if (t != null) {
t.cancel();
t = null;
}
t = Toast.makeText(ctx, message, Toast.LENGTH_SHORT);
}
public void show() {
t.show();
}
}
Solution 14 - Android
Using Madur's excellent answer above, I extended this into a class that would deal with different types of messages:
public class ToastManager {
private Toast toastWarningMessage;
private Toast toastAddMessage;
...
public void messageWarning(Context context, String message) {
if(toastWarningMessage == null) {
toastWarningMessage = Toast.makeText(context, message, Toast.LENGTH_SHORT);
} else {
toastWarningMessage.cancel();
toastWarningMessage.setText(message);
}
toastWarningMessage.show();
}
public void messageAdd(Context context, String message) {
if(toastAddMessage == null) {
toastAddMessage = Toast.makeText(context, message, Toast.LENGTH_SHORT);
} else {
toastAddMessage.cancel();
toastAddMessage.setText(message);
}
toastAddMessage.show();
}
...
}
And this is called from within my main activity:
ToastManager toastManager;
...
private void toastWarningMessage(String message) {
if(toastManager == null) toastManager = new ToastManager();
toastManager.messageWarning(this, message);
}
The reason for classifying the messages is to make sure that no important messages are overwritten. This solution seems easy to reuse as it only involves renaming the Toasts and the function names.
When the user spams the button, the toast will just cancel each time for the same message type. The only problem is if the user can spam a mix of messages. This leads to the first message repeating and once it finally expires the other messages showing once each. Not really a huge problem, but something to be aware of.
I haven't looked into possible downsides of having multiple Toast instances.
Solution 15 - Android
In my app, queued toasts appearing again and again when app goes into background so I did following to solve the problem.
Add code to detect when app goes into background. One way to register life cycle handler. For More detail ref
registerActivityLifecycleCallbacks(new MyLifecycleHandler());
App.inBackground = true;
when app goes to background and show toast using SmartToast class
public class SmartToast {
static ArrayList<WeakReference<Toast>> toasts = new ArrayList<>();
public static void showToast(@NonNull Context context,@NonNull String message){
//this will not allowed to show toast when app in background
if(App.inBackground) return;
Toast toast = Toast.makeText(context,message,Toast.LENGTH_SHORT);
toasts.add(new WeakReference<>(toast));
toast.show();
//clean up WeakReference objects itself
ArrayList<WeakReference<Toast>> nullToasts = new ArrayList<>();
for (WeakReference<Toast> weakToast : toasts) {
if(weakToast.get() == null) nullToasts.add(weakToast);
}
toasts.remove(nullToasts);
}
public static void cancelAll(){
for (WeakReference<Toast> weakToast : toasts) {
if(weakToast.get() != null) weakToast.get().cancel();
}
toasts.clear();
}
}
call SmartToast.cancelAll();
method when app goes into background to hide current and all pending toasts. Code is fun. Enjoy!
Solution 16 - Android
How about these !?
private Toast toast;
...
// Methods for short toast messages and long toast messages
private void showShortToast(String message) {
if(null != toast) toast.cancel();
(toast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT)).show();
}
private void showLongToast(String message) {
if(null != toast) toast.cancel();
(toast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG)).show();
}
and at onPause()
@Override
protected void onPause() {
...
if(null != toast) toast.cancel();
..
}
Solution 17 - Android
Here's how to disable toast messages, remove show()
expression.
//Disable notification message
Toast.makeText(this,"Message",Toast.LENGTH_SHORT);
//Enable notification message
Toast.makeText(this,"Message",Toast.LENGTH_SHORT).show();