Android cancela Toast al salir de la aplicación y cuando se muestra el brindis
He leído sobre este tipo de problema aquí, pero las respuestas no parecen estar funcionando.
Toast
un Toast
cuando el usuario hace clic en un botón. Cuando el usuario hace clic continuamente en el botón, el tostado sigue mostrándose una y otra vez incluso cuando el usuario sale de la actividad.
- Tostadas personalizadas para Android
- Android: crea un brindis anclado en una vista
- Android Vibrar en la tostada (Homer: Mmmm vibrar en la tostada)
- ¿De dónde viene esta tostada?
- ¿Puedo cancelar Toast anterior cuando quiero mostrar otro Toast?
La longitud de la tostada es corta. La longitud de la tostada no se puede cambiar ya que el texto es largo.
Esto es lo que he probado desde ahora:
Toast toast; toast=Toast.makeText(getApplicationContext(),"text",Toast.LENGTH_SHORT); if(toast.getView().isShown()==false){ toast.show(); }
Esto no funcionó.
Lo intenté :
if(toast.getView().isShown()==true){ toast.cancel(); }
En el onStop()
. Por alguna razón el método de cancelación nunca funciona.
Si pongo el .cancel()
antes de mostrar la aplicación … entonces habría otro cheque nulo para eso. Pero después de hacer eso también no funcionó. Puedo mostrar un cuadro de diálogo en lugar de un brindis, pero que no sería una solución.
¿Hay alguna manera de comprobar si un brindis se muestra o no?
Para referencia
-
Mensaje de brindis en Android
-
Cómo evitar un brindis si ya se muestra un brindis
-
Cómo evitar los solapamientos de tostadas múltiples
-
Cancelar un brindis ya abierto en Android
- Cómo hacer tostadas de otro hilo (sans runOnUiThread)
- Mostrar el widget de brindis debajo de una vista
- ¿Es posible esperar hasta que un brindis haya terminado de reanudar el método?
- ¿Puedo tener un ejemplo de mostrar un brindis usando runOnUiThread.
- Cómo cancelar Toast creado en un método diferente en android?
- ¿Mostrar dos mensajes Toast a la vez?
- Error de Android Toast
- Cancelar un brindis en Android antes de que aparezca
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.
Este código se puede encontrar en mi gistub Gistub:
- MobiRic / Boast
Si solo quieres saber cómo cancelar las notificaciones al salir de tu aplicación, encontrarás mucha ayuda allí. Si usted tiene mejoras o sugerencias, por favor no dude en bifurcación y ponerse en contacto. Esta es una respuesta muy antigua, pero el código ha sido estable en la producción de algunas aplicaciones durante algún tiempo.
BTW – esto debe ser un reemplazo directo de reemplazo para Toast
en la mayoría de los casos de uso.
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(); } }
En lugar de cancelar la tostada. Cambiar el texto. Por ejemplo
Toast t; t = Toast.makeText(this, "hi", 3000); t.show();
Cuando necesite una tostada diferente, utilice
t.setText("bye"); t.show();
Y si desea descartar el brindis simplemente llame a t.cancel()
Puede cancelar tostadas individuales llamando a cancel () en el objeto Toast. AFAIK, no hay forma de cancelar todos los Toasts pendientes, sin embargo.
Trate de mantener la marca de tiempo del último brindis y no permita nuevos brindis hasta que haya transcurrido un período de tiempo de espera.
Algo como:
private static final long TOAST_TIMEOUT_MS = 2000; // tweak this constant private static long lastToastTime = 0; public void onButtonClicked() { long now = System.currentTimeMillis(); if (lastToastTime + TOAST_TIMEOUT_MS < now) { Toast.makeText(...).show(); lastToastTime = now; } }
No me preocuparía por un solo pan tostado alrededor de un segundo después de que el usuario salga de la aplicación – este es un comportamiento bastante estándar.
- Cambiar la separación entre el grupo de encabezados y el primer elemento
- No se pudo aplicar el parche al actualizar el estudio de Android