如果已经显示了一个Toast,如何避免Toast

时间:2011-08-03 10:37:41

标签: android android-toast

我有几个SeekBaronSeekBarProgressStop(),我想要显示Toast消息。

但是如果在SeekBar上我快速执行操作,那么UI线程会以某种方式阻塞并且Toast消息等待直到UI线程空闲。

现在我担心的是,如果Toast消息已经显示,请避免使用新的Toast消息。或者是我们检查UI线程当前是否空闲的任何条件,然后我将显示Toast消息。

我尝试了两种方式,使用runOnUIThread()并创建了新的Handler

10 个答案:

答案 0 :(得分:56)

我尝试过各种各样的事情。起初我尝试使用cancel(),这对我没有影响(另见this answer)。

setDuration(n)我也没有来过任何地方。结果是,记录getDuration()它的值为0(如果makeText()的参数为Toast.LENGTH_SHORT)或1(如果makeText()的参数为{{1} }})。

最后,我尝试检查吐司的视图Toast.LENGTH_LONG。当然,如果没有显示吐司,则不是这样,但更重要的是,在这种情况下它会返回致命错误。所以我需要尝试捕捉错误。 现在,如果显示toast,isShown()将返回true。 利用isShown()我提出了方法:

isShown()

答案 1 :(得分:36)

以下是most popular answer的替代解决方案,没有try / catch。

public void showAToast (String message){
        if (mToast != null) {
            mToast.cancel();
        }
        mToast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
        mToast.show();
}

答案 2 :(得分:3)

开箱即用的干净解决方案。在您的活动中定义此内容:

private Toast toast;

/**
 * Use this to prevent multiple Toasts from spamming the UI for a long time.
 */
public void showToast(CharSequence text, int duration)
{
    if (toast == null)
        toast = Toast.makeText(this, text, duration);
    else
        toast.setText(text);
    toast.show();
}

public void showToast(int resId, int duration)
{
    showToast(getResources().getText(resId), duration);
}

答案 3 :(得分:2)

来自上面线程的增强功能,只有在使用相同的文字信息不可见时才显示吐司:

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

    }

答案 4 :(得分:1)

跟踪您上次展示吐司的时间,如果它在某个时间间隔内,则重新显示为无操作。

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

然后,

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

这并不完美,因为LENGTH_SHORTLENGTH_LONG的长度未定义,但在实践中效果很好。它具有优于其他解决方案的优势,您不需要保留Toast对象,并且调用语法仍然简洁。

答案 5 :(得分:1)

组合解决方案

对于我的情况,我需要取消当前的吐司,如果它显示并显示另一个。

这是为了解决当用户在仍在加载或不可用时请求服务的情况时我需要显示祝酒(如果请求的服务不同,可能会有所不同)。否则,祝酒词将按顺序显示,并且需要很长时间才能自动隐藏它们。

所以基本上我保存了创建toast的实例,以下代码是如何安全地取消它

synchronized public void cancel() {
    if(toast == null) {
        Log.d(TAG, "cancel: toast is null (occurs first time only)" );
        return;
    }
    final View view = toast.getView();
    if(view == null){
        Log.d(TAG, "cancel: view is null");
        return;
    }
    if (view.isShown()) {
        toast.cancel();
    }else{
        Log.d(TAG, "cancel: view is already dismissed");
    }
}

使用它我现在不用担心取消,如:

if (toastSingleton != null ) {
    toastSingleton.cancel();
    toastSingleton.showToast(messageText);
}else{
    Log.e(TAG, "setMessageText: toastSingleton is null");
}

showToast 取决于您如何实现它,因为我需要自定义我的吐司外观。

答案 6 :(得分:0)

适合停止堆叠,例如点击驱动吐司。基于@Adi的回答。

public Toast toast = null;
//....
public void favsDisplay(MenuItem item)
{
    if(toast == null) // first time around
    {
        Context context = getApplicationContext();
        CharSequence text = "Some text...";
        int duration = Toast.LENGTH_SHORT;
        toast = Toast.makeText(context, text, duration);
    }
    try
    {
        if(toast.getView().isShown() == false) // if false not showing anymore, then show it
            toast.show();
    }
    catch (Exception e)
    {}
}

答案 7 :(得分:0)

检查屏幕上是否显示Toast消息。 用于显示Toast消息创建单独的类。并使用此类的方法在检查Toast消息的可见性后显示Toast消息。使用此代码片段:

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

}

我希望这个解决方案可以帮到你。

由于

答案 8 :(得分:0)

添加了计时器,可在2秒后移除烤面包。

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

答案 9 :(得分:0)

我的解决方法是:

public class Utils {
    public static Toast showToast(Context context, Toast toast, String str) {
        if (toast != null)
            toast.cancel();
        Toast t = Toast.makeText(context, str, Toast.LENGTH_SHORT);
        t.show();
        return t;
    }
}

,并且调用方应为此方法的参数指定一个Toast成员,或者

class EasyToast {
    Toast toast;
    Context context;

    public EasyToast(Context context) {
        this.context = context;
    }

    public Toast show(String str) {
        if (toast != null)
            toast.cancel();
        Toast t = Toast.makeText(context, str, Toast.LENGTH_SHORT);
        t.show();
        return t;
    }

}

具有这样的帮助器类。