Как предотвратить множественные переполнения тоста - программирование
Подтвердить что ты не робот

Как предотвратить множественные переполнения тоста

Я использую общий "myToast", который я использую "myToast.cancel(), перед выпуском нового тоста. Для Android v2.3 и старше это отлично работает. Когда нужно отправить новый тост, старый, если он все еще отображается на экране, отменяется (и сразу исчезает), чтобы быть замененным новым тостом. Это позволяет избежать сложения кучи тостов, если пользователь нажимает клавишу несколько раз, для которой требуется предупреждение (и другие условия). Мой фактический случай - это один тост, когда нажимается неправильная клавиша, а другая появляется, если кнопка" Сброс" не нажата.

Для Android 4.0 и 4.1 выдача myToast.cancel() перед очередным тостом убивает как текущий, так и следующий тосты. Текущий API отмены() указывает, что он отменяет текущий И следующий тост (что кажется довольно глупым). Зачем отменять тост, который вы хотите мириться?

Любые идеи об отмене работают последовательно в версиях Android (и как это работает в версии 2.3 и старше)?

Я попробую немного неэлегантную двойную систему тоста с отслеживанием, для которой используется тост, но, похоже, такая боль работает вокруг этого плохого поведения в 4.x, чтобы получить то, что отлично работает и логично в старых версиях Android.


Хорошо, я решил это, но это не так чисто, как хотелось бы. Я реализовал двойной подход к тосту, где он чередуется между двумя тостами. Сначала мы определяем тосты для активности до 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.

4b9b3361

Ответ 1

Вместо вызова отмены. попробуйте сбросить текст и вызвать show(). Это должно отменить последний тост сам по себе

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

Если вы продолжаете использовать один и тот же myToast вместо того, чтобы создавать его каждый раз, я думаю, они не будут складываться.

Ответ 3

Решение nandeesh не работает для вас? Его решение было бы чище, чем использование двух разных тостов.

Например, (расширяя свой ответ) перед onCreate мы объявляем тост:

private Toast myToast;

и в onCreate нам придется инициализировать его с помощью makeToast (иначе мы получим ошибку):

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

и всякий раз, когда мы хотим показать тост, мы просто вызываем:

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

и это заменит предыдущий тост должным образом.

Ответ 4

Вот мой ответ, скопированный из другого подобного вопроса:

Класс 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 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();
    }

}

Ответ 5

Это мое решение прекрасно работает как для версий 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();

Ответ 6

Создайте объект Toast:

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

Ответ 7

создайте новую функцию и вызовите ее.

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