Android - Hide all shown Toast Messages

谁都会走 提交于 2019-12-28 01:51:50

问题


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 :)


回答1:


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();
}



回答2:


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.




回答3:


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();
   }
}



回答4:


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();



回答5:


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.




回答6:


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.




回答7:


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.




回答8:


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();
}



回答9:


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();



回答10:


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();

            }
        });



回答11:


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();
}
}



回答12:


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.




回答13:


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!




回答14:


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();
..
}



回答15:


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();


来源:https://stackoverflow.com/questions/2755277/android-hide-all-shown-toast-messages

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!