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
.
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
}
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();
}
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);
}
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();
}
}
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.
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.
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ą.
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)
{}
}
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
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");
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