2012-10-16 12 views
19

Ich habe einen gemeinsamen "myToast" verwendet, den ich "myToast.cancel(); vor dem Ausgeben eines neuen Toast verwenden. Für Android v2.3 und älter funktioniert das großartig. Wenn a neuer Toast muss gesendet werden, der alte, wenn er noch auf dem Bildschirm ist, wird abgebrochen (und verschwindet sofort), um durch den neuen Toast ersetzt zu werden.Dies vermeidet das Stapeln von einer Reihe von Toasts, wenn der Benutzer eine Taste mehrmals drückt die Warnung (und andere Bedingungen) Mein aktueller Fall ist ein Toast erscheint, wenn eine falsche Taste gedrückt wird, und ein anderes erscheint, wenn die Clear-Taste nicht gedrückt wirdSo verhindern Sie mehrere Toast-Überlappungen

Für Android 4.0 und 4.1, ein myToast.cancel() ausgeben vor dem nächsten Toast werden sowohl der aktuelle als auch der nächste Toast beendet, die aktuelle cancel() API zeigt an, dass der aktuelle UND der nächste Toast abgebrochen wird (was ziemlich blöd aussieht). Warum einen Toast abbrechen, den du aufstellen willst?

Irgendwelche Ideen, wie Abbruch funktioniert über Android-Versionen (und die Art, wie es in v2.3 und älter funktioniert) einheitlich?

Ich werde versuchen, einige unelegante Dual-Toast-System mit Tracking für die Toast verwendet wird, aber es scheint so ein Schmerz um dieses schlechte Verhalten in 4.x zu arbeiten, was perfekt und logisch in älteren Android-Versionen funktioniert.


Ok, ich habe es gelöst, aber es ist nicht annähernd so sauber, wie ich es mir gewünscht hätte. Ich habe einen Dual-Toast-Ansatz implementiert, bei dem es zwischen zwei Toasts wechselt. Zuerst definieren wir den Toast für die Aktivität vor der OnCreate:

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

Im OnCreate:

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

Und schließlich, wenn ich brauche den Toast zu führen und den vor Toast zugleich kündigen ich verwende etwas ähnliches wie:

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

Wenn Sie müssen nur einen vorhandenen Toast kündigen (bevor es mal aus) verwenden:

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

Getestet auf Nexus 7 (4.1), Emulator 4.0 und mehreren Geräten mit Android 2.2, 2.3.

+0

Wie stornieren Sie den alten Toast? Vor oder nach dem Erstellen des neuen? – TheZ

+0

Können Sie Ihren Code dort posten, wo Sie gerade anstoßen? – Ralgha

+0

Ich habe es vor dem neuen abgebrochen - deshalb ist es so seltsam, dass Android 4.x das neue verbirgt (aber die API zum Toast-Abbrechen erklärt, dass das passieren wird). Ich habe es in einer von mir erstellten Lösung bearbeitet, die funktioniert. Einfach nicht sehr gut aussehend. – Frank

Antwort

47

Statt Abbrechen aufrufen. Versuchen Sie, den Text zurückzusetzen und rufen Sie show() auf. Dies sollte die letzte Toast selbst

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

abbrechen Wenn Sie die gleiche myToast halten anstelle eines jedes Mal zu schaffen, ich denke, sie stapeln sich wont.

+0

Perfekt!Danke für das Teilen :) – Jona

2

cancel() tut nichts, was ich fürchte.

würde ich Crouton mit vorschlagen https://github.com/keyboardsurfer/Crouton

+0

Die Bibliothek ist gut, aber es löst dieses Problem nicht. – Ahmad

+0

mit toast.cancel() vor einem neuen Toast funktioniert teilweise - der vorhandene Toast, wenn vorhanden, verschwindet. Was sich geändert hat, ist in Android 4.x (vielleicht 3.x) versteckt es auch den nächsten Toast, den ich den ersten mit ersetzen möchte! – Frank

2

Hat nandeesh Lösung nicht für Sie arbeiten? Seine Lösung wäre sauberer als mit zwei verschiedenen Toasts.

Zum Beispiel (Erweiterung auf seine/ihre Antwort) vor onCreate wir den Toast erklären würde:

private Toast myToast; 

und in onCreate würden wir müssen es makeToast initialisieren verwenden (sonst würden wir bekommen Fehler):

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

und wann immer wir einen Toast wollen wir einfach nennen würde gezeigt werden:

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

und dies würde den vorherigen Toast ordnungsgemäß ersetzen.

+0

Ich bin mir nicht sicher, wo du gelesen hast, dass Nandeesh zwei Toasts vorschlägt. Er sagte ausdrücklich: "Wenn du den gleichen myToast verwendest, anstatt ihn jedes Mal zu erstellen, dann schätze ich nicht, dass sie sich stapeln. An diesem Punkt sehe ich keinen Unterschied zwischen deinen antworte und seins. Außerdem würde ich vorschlagen, dass Sie Ihre Antworten schreiben, ohne Ihre eigenen mit anderen Leuten zu vergleichen. Das klingt unhöflich für mich, besonders wenn Sie Dinge über ihre Antwort sagen, die falsch sind. – ForceMagic

+0

Wo habe ich gesagt, dass Nandeesh zwei Toast benutzte? Darüber hinaus war meine Antwort einfach zu erweitern und geben ein längeres Beispiel. – TSL

+0

Tut mir leid, das verwirrt mich immer noch. Hat die Nandeesh-Lösung nicht für dich funktioniert? Seine Lösung wäre sauberer als zwei verschiedene Toasts. Ich bin mir nicht sicher, warum du auf seine Antwort hinweisst und dann eine ähnliche postest, ich meine, der Teil, der in seiner Antwort fehlte, macht es nicht "nicht funktionierend" IMO. – ForceMagic

2

Hier ist meine Antwort von einer anderen ähnlichen Frage hier kopiert:

Der Boast Klasse erfüllt genau das, was Sie brauchen.


Der Trick ist, den Überblick über die letzten Toast zu halten, die gezeigt wurde, und dass man abzubrechen.

Was ich getan habe, ist ein Toast Wrapper zu erstellen, der eine statische Referenz auf den letzten angezeigten Toast enthält.

Wenn ich eine neue anzeigen muss, annulliere ich zuerst die statische Referenz, bevor ich die neue zeige (und sie in der statischen speichern).

Hier ist der vollständige Code des Boast Wrappers, den ich gemacht habe - es imitiert genug der Toast-Methoden für mich, es zu verwenden. Standardmäßig löscht die Boast die vorherige, so dass Sie keine Toast-Warteschlange erstellen, die darauf wartet, angezeigt zu werden.

Wenn Sie nur wissen möchten, wie Sie die Benachrichtigungen beim Beenden Ihrer App abbrechen können, finden Sie dort viele hilfreiche Informationen.


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

} 
+0

Ich liebe Ihre Lösung, und es funktioniert gut auf 4.x, aber haben Sie irgendeine Idee, warum es nicht auf 2.x funktioniert? (Ich habe 3.x nicht probiert) –

+0

Sorry keine Ahnung. Es ist Produktionscode und ich dachte, ich hätte es aus Gründen der Abwärtskompatibilität getestet. Werde umkehren, wenn ich in der Zukunft etwas herausfinden würde. –

1

Das ist meine Lösung funktioniert perfekt sowohl für 4. * und 2.3 Android-Versionen

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

neue Funktion erstellen und diese nennen.

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

einen Toast Objekt erstellen:

Toast toastobject=null; 

nun den folgenden Code verwenden, um den Toast anzuzeigen. Dies wird funktionieren finden Sie für mich

int index = clickCounter-1; 


    if(toastobject!= null) 
      { 
       toastobject.cancel(); 
      } 
      toastobject = Toast.makeText(this,"Toast Text" , Toast.LENGTH_SHORT); 
      listItems.remove(index); 
      toastobject.show(); 
Verwandte Themen