Cómo evitar los solapamientos de tostadas múltiples

He estado utilizando un "myToast" común que utilizo "myToast.cancel (), antes de emitir un nuevo tostado.Para Android v2.3 y mayores, esto funciona muy bien.Cuando un nuevo brindis tiene que ser enviado, el viejo Uno de ellos, si todavía está en la pantalla, se cancela (y desaparece inmediatamente) para ser reemplazado por el nuevo tostado Esto evita apilar un montón de tostadas si el usuario pulsa una tecla varias veces que necesita la alerta (y otras condiciones). El caso real es que una tostada aparece cuando se presiona una tecla equivocada y otra aparece si no se pulsa la tecla Borrar.

Para Android 4.0 y 4.1, emitir un myToast.cancel () antes de que el siguiente brindis mate tanto el brindis actual como el siguiente. La API de cancelación actual () indica que cancela la actual y la siguiente tostada (que parece bastante estúpida). ¿Por qué cancelar un brindis que desea poner?

Cualquier idea sobre cómo hacer que la cancelación funcione de manera consistente en las versiones de Android (y la forma en que funciona en v2.3 y versiones anteriores)?

Voy a probar un sistema de tostadas poco elegante con el seguimiento de que el pan tostado está en uso, pero parece que un dolor de trabajo alrededor de este mal comportamiento en 4.x para obtener lo que funciona perfectamente y lógicamente en las versiones más antiguas de Android.


Ok, lo resolví, pero no es tan limpio como me hubiera gustado. Implementé un enfoque de pan tostado doble, donde alterna entre dos tostadas. Primero definimos los brindis para la actividad antes de la OnCreate:

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

En el OnCreate:

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

Y, por último, cuando necesito mostrar la tostada y cancelar la tostada anterior al mismo tiempo, uso algo similar a:

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

Si necesita cancelar un tostado existente (antes de que se agoten) utilice:

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

Probado en Nexus 7 (4.1), Emulator 4.0, y varios dispositivos con Android 2.2, 2.3.

En lugar de llamar cancelar. Intente restablecer el texto y mostrar la llamada (). Esto debería cancelar el último brindis por sí mismo

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

Si sigues usando el mismo myToast en vez de crear uno cada vez supongo que no se apilarán.

cancel() no hace nada que tengo miedo.

Yo sugeriría usar Crouton https://github.com/keyboardsurfer/Crouton

¿La solución de nandeesh no funcionó para usted? Su solución sería más limpia que el uso de dos tostadas diferentes.

Por ejemplo, (expandiendo en su respuesta) antes de crecer, declararíamos el brindis:

 private Toast myToast; 

Y en onCreate tendríamos que inicializarlo usando makeToast (de lo contrario, obtendríamos un error):

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

Y siempre que queramos un brindis a ser mostrado simplemente llamar:

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

Y esto sustituiría a la tostada anterior correctamente.

Aquí está mi respuesta copiada de otra pregunta similar aquí:

  • Android cancela Toast al salir de la aplicación y cuando se muestra el brindis

La clase Boast logra exactamente lo que necesita.


El truco es hacer un seguimiento de la última Toast que se mostró, y cancelar esa.

Lo que he hecho es crear un contenedor de Toast , que contiene una referencia estática al último Toast que se muestra.

Cuando necesito mostrar una nueva, primero cancelo la referencia estática, antes de mostrar la nueva (y guardarla en la estática).

Aquí está el código completo de la envoltura de Boast que hice – imita bastante de los métodos de la tostada para que lo utilice. De forma predeterminada, el Boast cancelará el anterior, por lo que no creará una cola de Tostadas esperando a que se muestre.

Si solo quieres saber cómo cancelar las notificaciones al salir de tu aplicación, encontrarás mucha ayuda allí.


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

Esta solución mi funciona perfecto tanto para 4. * y 2.3 versiones de 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(); 

Crear un objeto de brindis:

 Toast toastobject=null; 

Ahora use el siguiente código para mostrar el brindis. Esto funcionará encontrar para mí

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

Crear una nueva función y llamar a esto.

 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); } } 
  • Tostada no se muestra en el Samsung Galaxy S3 (última actualización 4.1.2)
  • Error debido a la combinación no válida de Toast y OnClickListener
  • Cómo configurar el estilo tostado como tema?
  • Cómo personalizar Tostada en Android?
  • Android Toast para mostrar en la actividad anterior
  • Ocultar toast
  • ¿Cuál es la duración de un brindis LENGTH_LONG y LENGTH_SHORT
  • ¿Cómo hago un brindis de una clase que no es de actividad?
  • Establecer Toast Aparecer Longitud
  • Desea ocultar la tostada de Android cuando la aplicación está en segundo plano
  • Cómo personalizar el brindis en Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.