43

いくつかSeekBarありますonSeekBarProgressStop()が、メッセージを表示したいですToast

しかしSeekBar、アクションを迅速に実行すると、UIスレッドがブロックされ、ToastメッセージはUIスレッドが解放されるまで待機します。

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

runOnUIThread()新しいを使用して作成することによって、両方の方法でそれを試しましたHandler

4

10 に答える 10

63

私はこれを行うためにさまざまなことを試みました。最初はcancel()、効果がなかったを使ってみました(この回答も参照してください)。

私もどこに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
    }
于 2012-07-11T21:25:34.230 に答える
42

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

public void showAToast (String message){
        if (mToast != null) {
            mToast.cancel();
        }
        mToast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
        mToast.show();
}
于 2015-04-11T03:43:58.460 に答える
2

最後にトーストを表示した時間を追跡し、一定の間隔内に収まった場合は再表示しないようにします。

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

于 2012-08-27T19:06:20.163 に答える
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 を実装する方法はあなた次第です

于 2017-02-27T10:51:23.840 に答える
0

クリック駆動のトーストなど、スタッキングを停止するのに適しています。@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)
    {}
}
于 2015-06-13T15:47:55.760 に答える
0

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

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

}

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

ありがとう

于 2018-02-22T08:15:54.497 に答える