How to avoid a Toast if there's one Toast alre

2019-01-14 10:59发布

I have several SeekBar and onSeekBarProgressStop(), I want to show a Toast message.

But if on SeekBar I perform the action rapidly then UI thread somehow blocks and Toast message waits till UI thread is free.

Now my concern is to avoid the new Toast message if the Toast message is already displaying. Or is their any condition by which we check that UI thread is currently free then I'll show the Toast message.

I tried it in both way, by using runOnUIThread() and also creating new Handler.

9条回答
啃猪蹄的小仙女
2楼-- · 2019-01-14 11:02

Check for showing toast message on screen either it is displayed or not. For Showing a toast message Make a separate class. And use the method of this class which display the toast message after checking the visibility of the toast message. Use This Snippet of code:

public class AppToast {

private static Toast toast;

public static void showToast(Context context, String message) {
    try {
        if (!toast.getView().isShown()) {
            toast=Toast.makeText(context, message, Toast.LENGTH_SHORT);
            toast.show();
        }
    } catch (Exception ex) {
        toast=Toast.makeText(context,message,Toast.LENGTH_SHORT);
        toast.show();
    }
}

}

I hope this solution will help you.

Thanks

查看更多
孤傲高冷的网名
3楼-- · 2019-01-14 11:03

The following is an alternative solution to the most popular answer, without the try/catch.

public void showAToast (String message){
        if (mToast != null) {
            mToast.cancel();
        }
        mToast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
        mToast.show();
}
查看更多
对你真心纯属浪费
4楼-- · 2019-01-14 11:09

keep track of the last time you showed the toast, and make re-showing it a no-op if it falls within some interval.

public class RepeatSafeToast {

    private static final int DURATION = 4000;

    private static final Map<Object, Long> lastShown = new HashMap<Object, Long>();

    private static boolean isRecent(Object obj) {
        Long last = lastShown.get(obj);
        if (last == null) {
            return false;
        }
        long now = System.currentTimeMillis();
        if (last + DURATION < now) {
            return false;
        }
        return true;
    }

    public static synchronized void show(Context context, int resId) {
        if (isRecent(resId)) {
            return;
        }
        Toast.makeText(context, resId, Toast.LENGTH_LONG).show();
        lastShown.put(resId, System.currentTimeMillis());
    }

    public static synchronized void show(Context context, String msg) {
        if (isRecent(msg)) {
            return;
        }
        Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
        lastShown.put(msg, System.currentTimeMillis());
    }
}

and then,

RepeatSafeToast.show(this, "Hello, toast.");
RepeatSafeToast.show(this, "Hello, toast."); // won't be shown
RepeatSafeToast.show(this, "Hello, toast."); // won't be shown
RepeatSafeToast.show(this, "Hello, toast."); // won't be shown

this isn't perfect, since the length of LENGTH_SHORT and LENGTH_LONG are undefined, but it works well in practice. it has the advantage over other solutions that you don't need to hold on to the Toast object and the call syntax remains terse.

查看更多
狗以群分
5楼-- · 2019-01-14 11:10

I've tried a variety of things to do this. At first I tried using the cancel(), which had no effect for me (see also this answer).

With setDuration(n) I wasn't coming to anywhere either. It turned out by logging getDuration() that it carries a value of 0 (if makeText()'s parameter was Toast.LENGTH_SHORT) or 1 (if makeText()'s parameter was Toast.LENGTH_LONG).

Finally I tried to check if the toast's view isShown(). Of course it isn't if no toast is shown, but even more, it returns a fatal error in this case. So I needed to try and catch the error. Now, isShown() returns true if a toast is displayed. Utilizing isShown() I came up with the method:

    /**
     * <strong>public void showAToast (String st)</strong></br>
     * this little method displays a toast on the screen.</br>
     * it checks if a toast is currently visible</br>
     * if so </br>
     * ... it "sets" the new text</br>
     * else</br>
     * ... it "makes" the new text</br>
     * and "shows" either or  
     * @param st the string to be toasted
     */

    public void showAToast (String st){ //"Toast toast" is declared in the class
        try{ toast.getView().isShown();     // true if visible
            toast.setText(st);
        } catch (Exception e) {         // invisible if exception
            toast = Toast.makeText(theContext, st, toastDuration);
            }
        toast.show();  //finally display it
    }
查看更多
做自己的国王
6楼-- · 2019-01-14 11:10

The enhanced function from above thread, which will show toast only if not visible with same text message:

 public void showSingleToast(){
        try{
            if(!toast.getView().isShown()) {    
                toast.show();
            }
        } catch (Exception exception) {
            exception.printStackTrace();       
            Log.d(TAG,"Toast Exception is "+exception.getLocalizedMessage());
            toast = Toast.makeText(this.getActivity(),   getContext().getString(R.string.no_search_result_fou`enter code here`nd), Toast.LENGTH_SHORT);
            toast.show();
        }

    }
查看更多
我想做一个坏孩纸
7楼-- · 2019-01-14 11:12

added timer to remove the toast after 2 seconds.

private Toast toast;

public void showToast(String text){
        try {
            toast.getView().isShown();
            toast.setText(text);
        }catch (Exception e){
            toast = Toast.makeText(mContext, text, Toast.LENGTH_SHORT);
        }
        if(toast.getView().isShown()){
            new Timer().schedule(new TimerTask() {
                @Override
                public void run() {
                    toast.cancel();
                }
            }, 2000);
        }else{
            toast.show();
        }
    }

showToast("Please wait");
查看更多
登录 后发表回答