Jak uniknąć toastu, jeśli jest już pokazany jeden Toast

Mam kilka SeekBar i onSeekBarProgressStop(), chcę pokazać Toast wiadomość.

Ale jeśli na SeekBar wykonam akcję szybko wtedy wątek UI jakoś się blokuje i Toast wiadomość czeka aż wątek UI będzie wolny.

Teraz moim zmartwieniem jest uniknięcie nowej wiadomości Toast, Jeśli wiadomość Toast jest już wyświetlana. Lub jest ich dowolny warunek, według którego sprawdzamy, że wątek UI jest obecnie wolny, a następnie pokażę wiadomość Toast.

Próbowałem w obie strony, używając runOnUIThread() i również tworzenie nowego Handler.

Author: Sufian, 2011-08-03

10 answers

Próbowałem różnych rzeczy, aby to zrobić. Na początku próbowałem użyć cancel(), co nie miało dla mnie żadnego efektu(patrz również ta odpowiedź ).

Z setDuration(n) ja też nigdzie nie przychodziłem. Po zalogowaniu getDuration() okazało się, że ma wartość 0 (jeśli parametr makeText() był Toast.LENGTH_SHORT) lub 1 (Jeśli parametr makeText() był Toast.LENGTH_LONG).

W końcu próbowałem sprawdzić, czy Widok tosta isShown(). Oczywiście nie jest, jeśli nie jest wyświetlany toast, ale co więcej, zwraca błąd krytyczny w tym case. Więc musiałem spróbować złapać błąd. isShown() zwraca true, jeśli wyświetlony jest toast. Wykorzystując isShown() wymyśliłem metodę:

    /**
     * <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
    }
 59
Author: Addi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:15

Poniżej znajduje się alternatywne rozwiązanie dla najpopularniejszej odpowiedzi , bez try/catch.

public void showAToast (String message){
        if (mToast != null) {
            mToast.cancel();
        }
        mToast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
        mToast.show();
}
 40
Author: J Wang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:15

Czysty roztwór, który działa po wyjęciu z pudełka. Zdefiniuj to na swojej aktywności:

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
Author: wvdz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-21 15:29:42

Ulepszona funkcja z powyższego wątku, która wyświetli toast tylko wtedy, gdy nie jest widoczna z tym samym tekstem:

 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
Author: Sandeep Kharat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-06 13:46:36

Śledź ostatni raz, kiedy pokazałeś toast, i spraw, aby ponowne pokazanie było nieaktywne, jeśli spadnie w pewnym odstępie czasu.

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

I wtedy,

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

To nie jest idealne, ponieważ długość LENGTH_SHORT i LENGTH_LONG są niezdefiniowane, ale działa to dobrze w praktyce. ma tę przewagę nad innymi rozwiązaniami, że nie trzeba trzymać się obiektu Toast, a składnia wywołania pozostaje krótka.

 1
Author: Jeffrey Blattman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-27 19:06:20

A combined solution

W moim przypadku, musiałem anulować obecny toast, jeśli pokazano i Wyświetlono inny.

Miało to rozwiązać scenariusz, gdy użytkownik prosi o usługę, gdy jest jeszcze ładowana lub nie jest dostępna, muszę pokazać toast(może mi się różnić, jeśli żądana usługa jest inna). W przeciwnym razie, toasty będą wyświetlane w porządku i zajmie bardzo dużo czasu, aby ukryć je automatycznie.

Więc w zasadzie zapisuję instancję toastu am tworzenie i poniższy kod jest jak go anulować safly

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

I aby go używać, nie mogę się teraz martwić o anulowanie jak w:

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

TheshowToast zależy od Ciebie, jak go zaimplementować, ponieważ potrzebowałem niestandardowego wyglądu mojego tosta.

 1
Author: hannunehg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-27 10:51:23

Moje rozwiązanie to:

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

I wywołujący powinien mieć toast za parametr tej metody, lub

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

}

Mieć taką klasę pomocniczą.

 1
Author: fung,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-27 04:23:29

Dobry do przerywania układania np. tostów z kliknięciem. Na podstawie odpowiedzi @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
Author: forward creating,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-13 15:47:55

Sprawdź, czy wiadomość tostowa jest wyświetlana lub nie. Za pokazanie wiadomości toastu zrób oddzielną klasę. I użyj metody tej klasy, która wyświetla wiadomość toast po sprawdzeniu widoczności wiadomości toast. Użyj tego fragmentu kodu:

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

}
Mam nadzieję, że to rozwiązanie wam pomoże.

Thanks

 0
Author: Aman Goyal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-22 08:15:54

Dodano timer, aby usunąć tost po 2 sekundach.

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");
 0
Author: ryan christoper lucasan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-20 09:44:47