web-dev-qa-db-ja.com

複数のトーストの重複を防ぐ方法

新しいトーストを発行する前に「myToast.cancel()」を使用する一般的な「myToast」を使用しています。Android v2.3以前の場合、これはうまく機能します。新しいトースト送信する必要がある場合、古いトーストがまだ画面上にある場合はキャンセルされ(すぐに消えて)、新しいトーストに置き換えられます。これにより、ユーザーがアラートを必要とするキーを複数回押したときにトーストの束が積み重なるのを防ぎます(およびその他の条件)私の実際のケースでは、間違ったキーが押されたときにトーストが表示され、クリアキーが押されていない場合に別のトーストが表示されます。

Android 4.0および4.1では、次のトーストの前にmyToast.cancel()を発行すると、現在のトーストと次のトーストの両方が強制終了されます。現在のcancel() AP​​Iは、現在のAND次のトーストをキャンセルすることを示しています(これはかなり馬鹿げているようです)。トーストをキャンセルしたいのはなぜですか?

キャンセルをAndroidバージョン全体で一貫して機能させるためのアイデア(およびv2.3以前での機能)

どのトーストが使用されているかを追跡するいくつかの洗練されていないデュアルトーストシステムを試しますが、4.xのこの悪い動作を回避して、古いAndroidバージョンで完全かつ論理的に機能するものを取得するのは大変な苦労のようです。 。


はい、解決しましたが、思ったほどきれいではありません。 2つのトーストを交互に使用するデュアルトーストアプローチを実装しました。最初に、OnCreateの前にアクティビティのトーストを定義します。

Toast toast0;
Toast toast1;
private static boolean lastToast0 = true;

OnCreateでは:

toast0 = new Toast(getApplicationContext());
toast0.cancel();
toast1 = new Toast(getApplicationContext());
toast1.cancel();

そして最後に、トーストを表示すると同時に前のトーストをキャンセルする必要がある場合は、次のようなものを使用します。

if (lastToast0) {
    toast0.cancel();
    toast1.setDuration(Toast.LENGTH_LONG);
    toast1.setText("new message");
    toast1.show();
    lastToast0 = false;
} else {
    toast1.cancel();
    toast0.setDuration(Toast.LENGTH_LONG);
    toast0.setText("new message");
    toast0.show();
    lastToast0 = true;
}

既存のトーストを(タイムアウトする前に)キャンセルする必要がある場合は、次を使用します。

toast0.cancel();
toast1.cancel();

Nexus 7(4.1)、エミュレータ4.0、およびAndroid 2.2、2.3を搭載した複数のデバイスでテスト済み。

26
Frank

cancel()を呼び出す代わりに。テキストをリセットしてshow()を呼び出してみてください。これで最後のトーストが自動的にキャンセルされます

myToast.setText("wrong key")
myToast.show();

同じmyToastを使い続ける場合、毎回作成するのではなく、スタックしないと思います。

50
nandeesh

ナンディーシュのソリューションはあなたにとってうまくいきませんでしたか?彼の解決策は、2つの異なるトーストを使用するよりもクリーンです。

たとえば、onCreateの前に(彼/彼女の答えを展開して)トーストを宣言します。

private Toast myToast;

onCreateでは、makeToastを使用して初期化する必要があります(そうしないと、エラーが発生します)。

myToast = Toast.makeText(getApplicationContext(), null, Toast.LENGTH_SHORT);

トーストを表示したいときはいつでも、次のように呼び出すだけです。

myToast.setText("some text");
myToast.show();

これは以前のトーストを適切に置き換えます。

3
TSL

cancel()は、私が恐れていることを何もしません。

Croutonの使用をお勧めします https://github.com/keyboardsurfer/Crouton

2
Joe Simpson

ここに私の別の同様の質問からコピーされた私の答えがあります:

Boastクラスは、必要なものを正確に実現します。


トリックは、最後に表示されたToastを追跡し、それをキャンセルすることです。

私がやったことは、最後に表示されたトーストへの静的参照を含むToastラッパーを作成することです。

新しいものを表示する必要がある場合は、静的参照をキャンセルしてから、新しい参照を表示します(そして静的参照に保存します)。

これが私が作成したBoastラッパーの完全なコードです。これは、使用するために十分なToastメソッドを模倣しています。デフォルトでは、Boastは前のものをキャンセルするため、表示されるのを待っているトーストのキューを構築しません。

アプリを終了するときに通知をキャンセルする方法だけを知りたい場合は、そこに多くの助けがあります。


package mobi.glowworm.lib.ui.widget;

import Android.annotation.SuppressLint;
import Android.content.Context;
import Android.content.res.Resources;
import Android.support.annotation.Nullable;
import Android.widget.Toast;

import Java.lang.ref.WeakReference;

/**
 * {@link Toast} decorator allowing for easy cancellation of notifications. Use this class if you
 * want subsequent Toast notifications to overwrite current ones. </p>
 * <p/>
 * By default, a current {@link Boast} notification will be cancelled by a subsequent notification.
 * This default behaviour can be changed by calling certain methods like {@link #show(boolean)}.
 */
public class Boast {
    /**
     * Keeps track of certain Boast notifications that may need to be cancelled. This functionality
     * is only offered by some of the methods in this class.
     * <p>
     * Uses a {@link WeakReference} to avoid leaking the activity context used to show the original {@link Toast}.
     */
    @Nullable
    private volatile static WeakReference<Boast> weakBoast = null;

    @Nullable
    private static Boast getGlobalBoast() {
        if (weakBoast == null) {
            return null;
        }

        return weakBoast.get();
    }

    private static void setGlobalBoast(@Nullable Boast globalBoast) {
        Boast.weakBoast = new WeakReference<>(globalBoast);
    }


    // ////////////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * Internal reference to the {@link Toast} object that will be displayed.
     */
    private Toast internalToast;

    // ////////////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * Private constructor creates a new {@link Boast} from a given {@link Toast}.
     *
     * @throws NullPointerException if the parameter is <code>null</code>.
     */
    private Boast(Toast toast) {
        // null check
        if (toast == null) {
            throw new NullPointerException("Boast.Boast(Toast) requires a non-null parameter.");
        }

        internalToast = toast;
    }

    // ////////////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * Make a standard {@link Boast} that just contains a text view.
     *
     * @param context  The context to use. Usually your {@link Android.app.Application} or
     *                 {@link Android.app.Activity} object.
     * @param text     The text to show. Can be formatted text.
     * @param duration How long to display the message. Either {@link Toast#LENGTH_SHORT} or
     *                 {@link Toast#LENGTH_LONG}
     */
    @SuppressLint("ShowToast")
    public static Boast makeText(Context context, CharSequence text, int duration) {
        return new Boast(Toast.makeText(context, text, duration));
    }

    /**
     * Make a standard {@link Boast} that just contains a text view with the text from a resource.
     *
     * @param context  The context to use. Usually your {@link Android.app.Application} or
     *                 {@link Android.app.Activity} object.
     * @param resId    The resource id of the string resource to use. Can be formatted text.
     * @param duration How long to display the message. Either {@link Toast#LENGTH_SHORT} or
     *                 {@link Toast#LENGTH_LONG}
     * @throws Resources.NotFoundException if the resource can't be found.
     */
    @SuppressLint("ShowToast")
    public static Boast makeText(Context context, int resId, int duration)
            throws Resources.NotFoundException {
        return new Boast(Toast.makeText(context, resId, duration));
    }

    /**
     * Make a standard {@link Boast} that just contains a text view. Duration defaults to
     * {@link Toast#LENGTH_SHORT}.
     *
     * @param context The context to use. Usually your {@link Android.app.Application} or
     *                {@link Android.app.Activity} object.
     * @param text    The text to show. Can be formatted text.
     */
    @SuppressLint("ShowToast")
    public static Boast makeText(Context context, CharSequence text) {
        return new Boast(Toast.makeText(context, text, Toast.LENGTH_SHORT));
    }

    /**
     * Make a standard {@link Boast} that just contains a text view with the text from a resource.
     * Duration defaults to {@link Toast#LENGTH_SHORT}.
     *
     * @param context The context to use. Usually your {@link Android.app.Application} or
     *                {@link Android.app.Activity} object.
     * @param resId   The resource id of the string resource to use. Can be formatted text.
     * @throws Resources.NotFoundException if the resource can't be found.
     */
    @SuppressLint("ShowToast")
    public static Boast makeText(Context context, int resId) throws Resources.NotFoundException {
        return new Boast(Toast.makeText(context, resId, Toast.LENGTH_SHORT));
    }

    // ////////////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * Show a standard {@link Boast} that just contains a text view.
     *
     * @param context  The context to use. Usually your {@link Android.app.Application} or
     *                 {@link Android.app.Activity} object.
     * @param text     The text to show. Can be formatted text.
     * @param duration How long to display the message. Either {@link Toast#LENGTH_SHORT} or
     *                 {@link Toast#LENGTH_LONG}
     */
    public static void showText(Context context, CharSequence text, int duration) {
        Boast.makeText(context, text, duration).show();
    }

    /**
     * Show a standard {@link Boast} that just contains a text view with the text from a resource.
     *
     * @param context  The context to use. Usually your {@link Android.app.Application} or
     *                 {@link Android.app.Activity} object.
     * @param resId    The resource id of the string resource to use. Can be formatted text.
     * @param duration How long to display the message. Either {@link Toast#LENGTH_SHORT} or
     *                 {@link Toast#LENGTH_LONG}
     * @throws Resources.NotFoundException if the resource can't be found.
     */
    public static void showText(Context context, int resId, int duration)
            throws Resources.NotFoundException {
        Boast.makeText(context, resId, duration).show();
    }

    /**
     * Show a standard {@link Boast} that just contains a text view. Duration defaults to
     * {@link Toast#LENGTH_SHORT}.
     *
     * @param context The context to use. Usually your {@link Android.app.Application} or
     *                {@link Android.app.Activity} object.
     * @param text    The text to show. Can be formatted text.
     */
    public static void showText(Context context, CharSequence text) {
        Boast.makeText(context, text, Toast.LENGTH_SHORT).show();
    }

    /**
     * Show a standard {@link Boast} that just contains a text view with the text from a resource.
     * Duration defaults to {@link Toast#LENGTH_SHORT}.
     *
     * @param context The context to use. Usually your {@link Android.app.Application} or
     *                {@link Android.app.Activity} object.
     * @param resId   The resource id of the string resource to use. Can be formatted text.
     * @throws Resources.NotFoundException if the resource can't be found.
     */
    public static void showText(Context context, int resId) throws Resources.NotFoundException {
        Boast.makeText(context, resId, Toast.LENGTH_SHORT).show();
    }

    // ////////////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * Close the view if it's showing, or don't show it if it isn't showing yet. You do not normally
     * have to call this. Normally view will disappear on its own after the appropriate duration.
     */
    public void cancel() {
        internalToast.cancel();
    }

    /**
     * Show the view for the specified duration. By default, this method cancels any current
     * notification to immediately display the new one. For conventional {@link Toast#show()}
     * queueing behaviour, use method {@link #show(boolean)}.
     *
     * @see #show(boolean)
     */
    public void show() {
        show(true);
    }

    /**
     * Show the view for the specified duration. This method can be used to cancel the current
     * notification, or to queue up notifications.
     *
     * @param cancelCurrent <code>true</code> to cancel any current notification and replace it with this new
     *                      one
     * @see #show()
     */
    public void show(boolean cancelCurrent) {
        // cancel current
        if (cancelCurrent) {
            final Boast cachedGlobalBoast = getGlobalBoast();
            if ((cachedGlobalBoast != null)) {
                cachedGlobalBoast.cancel();
            }
        }

        // save an instance of this current notification
        setGlobalBoast(this);

        internalToast.show();
    }

}
2

この私のソリューションは、4。*と2.3の両方に最適ですAndroidバージョン

static Toast toast;
.....

if (toast != null)
    toast.cancel();

boolean condition = Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB;
if ((toast == null && condition) || !condition)
    toast = Toast.makeText(context, text, Toast.LENGTH_LONG);
if ((toast != null && condition))
    toast.setText(text);
toast.show();
1
Alex Halevin

トーストオブジェクトを作成します。

Toast toastobject=null;

次のコードを使用してトーストを表示します。これでうまくいきます

    int index = clickCounter-1;


    if(toastobject!= null)
            {
                toastobject.cancel();
            }
            toastobject = Toast.makeText(this,"Toast Text" , Toast.LENGTH_SHORT);
            listItems.remove(index);
            toastobject.show();
1
Vignesh KM

新しい関数を作成し、これを呼び出します。

ImageButton ABtn = (ImageButton) findViewById(R.id.Btn);
ABtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{       
SETToast("mytext");
}
});

    private Toast toast = null;

public void SETToast( String text)
{
  if(toast==null)
  {
     toast = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT); 
     toast.show();
     final Handler handler = new Handler(); 
     handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            toast=null;
        }
     }, 2000);
  }
  else
  {
      toast.setText(text);
  }   
}
0
Ehsan Jelodar