web-dev-qa-db-ja.com

すでに表示されているトーストがある場合にトーストを回避する方法

SeekBaronSeekBarProgressStop()がいくつかあります。Toastメッセージを表示したいと思います。

しかし、SeekBarがオンの場合、アクションをすばやく実行すると、UIスレッドが何らかの理由でブロックし、UIスレッドが解放されるまでToastメッセージが待機します。

Toastメッセージが既に表示されている場合は、新しいToastメッセージを回避することが私の懸念です。または、UIスレッドが現在フリーであることを確認するための条件である場合は、Toastメッセージを表示します。

runOnUIThread()を使用し、新しいHandlerを作成することで、両方の方法で試しました。

38
Deepak Goel

私はこれを行うためにさまざまなことを試みました。最初はcancel()を試してみましたが、効果はありませんでした( this answer も参照)。

setDuration(n)を使用して、どこにも行かなかった。ロギングgetDuration()により、値が0(makeText()のパラメーターがToast.LENGTH_SHORTの場合)または1(makeText()のパラメーターがToast.LENGTH_LONGの場合)であることが判明しました。

最後に、トーストのビューがisShown()かどうかを確認しようとしました。もちろんトーストが表示されない場合はそうではありませんが、この場合はさらに致命的なエラーを返します。だから私はエラーをキャッチして試す必要がありました。現在は、トーストが表示されている場合、isShown()はtrueを返します。 isShown()を使用して、私はメソッドを思いつきました:

    /**
     * <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
    }
58
Addi

以下は、try/catchを使用しない 最も一般的な回答 の代替ソリューションです。

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

そのまま使用できるクリーンなソリューション。これをアクティビティで定義します。

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
wvdz

上記のスレッドの拡張機能。同じテキストメッセージで表示されない場合にのみトーストを表示します。

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

    }
2
Sandeep Kharat

トーストを最後に表示した時間を追跡し、ある間隔内に収まった場合は、何も表示しないようにします。

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オブジェクトを保持する必要がない他のソリューションよりも優れており、呼び出し構文は簡潔なままです。

1

組み合わせたソリューション

私の場合、現在のトーストが表示されて別のトーストが表示された場合はキャンセルする必要がありました。

これは、まだロード中または利用できないときにユーザーがサービスを要求するシナリオを解決するためのものでした。トーストを表示する必要があります(要求されたサービスが異なる場合は異なる場合があります)。そうしないと、トーストが順番に表示され続け、自動的に非表示になるまでに非常に長い時間がかかります。

だから基本的に私は作成しているトーストのインスタンスを保存し、次のコードはそれをキャンセルする方法です

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は、トーストのカスタムルックが必要だったため、実装方法はあなた次第です。

1
hannunehg

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

画面にトーストメッセージが表示されるかどうかを確認します。トーストメッセージを表示するために別のクラスを作ります。トーストメッセージの可視性を確認した後、トーストメッセージを表示するこのクラスのメソッドを使用します。このコードのスニペットを使用してください:

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

}

このソリューションがお役に立てば幸いです。

ありがとう

0
Aman Goyal

スタッキングの停止に適しています。クリックドリブントースト。 @Addiの回答に基づいています。

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

}

このようなヘルパークラスがあります。

0
fung