Ich benutze eine Snackbar aus der com.android.support:design:22.2.0
Bibliothek. Ich benutze es, um Löschungen rückgängig zu machen. Um mir das Leben zu erleichtern, werde ich die Benutzeroberfläche so aussehen lassen, als würden Dinge tatsächlich aus der Datenquelle gelöscht. Wenn die Schaltfläche zum Rückgängigmachen in der Snackleiste nicht gedrückt wird, führen Sie die Löschvorgänge aus der Datenquelle durch. Ich möchte also wissen, wann die Snackbar nicht mehr sichtbar ist, damit die Elemente sicher gelöscht werden können.
Ich kann getView () in der Snackbar aufrufen, bin mir aber nicht sicher, welchen Listener ich verwenden soll. Ich habe es versucht, setOnSystemUiVisibilityChangeListener()
aber das hat nicht funktioniert. Ich glaube, es ist nur für die Systemstatusleiste.
Außerdem kann die Snackbar nicht erweitert werden, da sie über einen privaten Konstruktor verfügt.
Antworten:
Die Google Design Library unterstützt Snackbar-Rückrufe in Version 23. Siehe Snackbar-Dokumente und Rückrufdokumente . Sie werden dann benachrichtigt, wenn die Snackbar entlassen wird (und auch wenn sie angezeigt wird) und auch die Art der Entlassung, wenn dies für Sie nützlich ist:
snackbar.addCallback(new Snackbar.Callback() { @Override public void onDismissed(Snackbar snackbar, int event) { //see Snackbar.Callback docs for event details ... } @Override public void onShown(Snackbar snackbar) { ... } });
quelle
snackbar.addCallback(new Snackbar.Callback() { @Override public void onDismissed(Snackbar snackbar, int event) { if (event == Snackbar.Callback.DISMISS_EVENT_TIMEOUT) { // Snackbar closed on its own } } @Override public void onShown(Snackbar snackbar) { ... } });
quelle
if (event != Snackbar.Callback.DISMISS_EVENT_ACTION)
stattdessen zu überprüfen, ob Ihre Entlassungslogik nicht ausgeführt wird, wenn der Benutzer manuell entlässt oder eine Snackbar von einer anderen aufeinanderfolgenden Snackbar entlassen wird.event == Snackbar.Callback.DISMISS_EVENT_TIMEOUT
Snackbar.addCallback in Kotlin
val snackBar = Snackbar .make(view, "Text Snackbar", Snackbar.LENGTH_LONG) .addCallback(object : BaseTransientBottomBar.BaseCallback<Snackbar>() { override fun onShown(transientBottomBar: Snackbar?) { super.onShown(transientBottomBar) } override fun onDismissed(transientBottomBar: Snackbar?, event: Int) { super.onDismissed(transientBottomBar, event) } }) val snackBarView = snackBar.view snackBarView.setBackgroundColor(Color.RED) snackBar.show()
quelle
Kürzlich bin ich selbst auf diese Angelegenheit gestoßen, als zum Scrollen und Zeigen von Snackback zu viele gezeigt wurden, bevor die erste überhaupt verschwand. Ich musste einen Weg finden, um zu wissen, ob die App die Snackbar hätte einrichten sollen.
Ich persönlich habe diese Lösung gefunden.
Es ist wahr, dass die Snackbar selbst keine Art von Listener für ihren Status / ihre Sichtbarkeit bietet, aber Sie können das Ansichtsobjekt trotzdem aus der Snackbar herausholen (getView ();). Über das Ansichtsobjekt haben Sie die Möglichkeit, mithilfe einer Vielzahl von Methoden Listener hinzuzufügen.
Um es zu implementieren, müssen Sie die übliche "All-in-One-Line" -Toast- / Snackbar-Verwendung verlassen, da das Hinzufügen von Listenern ungültig ist .
Ich persönlich habe OnAttachStateChangeListener gefunden, um meine Anforderungen zu erfüllen.
Lassen Sie einen Snipper mit meinem Code fallen, falls er für Sie nützlich sein könnte.
Snackbar snack = Snackbar.make(getView(), "My Placeholder Text", Snackbar.LENGTH_LONG); snack.getView().addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { @Override public void onViewAttachedToWindow(View v) { canDisplaySnackbar = false; } @Override public void onViewDetachedFromWindow(View v) { Handler h = new Handler(); h.postDelayed(new Runnable() { @Override public void run() { canDisplaySnackbar = true; } }, 1000); } }); snack.show();
Bitte beachten Sie, dass dies nur meine Implementierung für mein eigenes Problem ist. Der Handler mit einem postDelayed Runnable passt möglicherweise nicht einmal zu Ihrem Fall. Es war nur, um einen allgemeinen Überblick über die Implementierung zu geben, die ich unter Verwendung eines Snippets vorgeschlagen habe, das ich bereits besitze.
quelle
Um benachrichtigt zu werden, wenn eine Snackbar angezeigt oder geschlossen wurde, können Sie eine Snackbar.Callback über setCallback (Callback) bereitstellen.
quelle
onDismissed wird auch aufgerufen, wenn auf die Aktion Text geklickt wird, aus diesem Grund muss eine Bedingung wie gesetzt werden
event == Snackbar.Callback.DISMISS_EVENT_TIMEOUT
Und jetzt sieht der neue Code wie folgt aus.
final Snackbar snackBar = Snackbar.make(findViewById(R.id.root_layout), result, Snackbar.LENGTH_LONG); snackbar.addCallback(new Snackbar.Callback() { @Override public void onDismissed(Snackbar snackbar, int event) { if (event == Snackbar.Callback.DISMISS_EVENT_TIMEOUT) { // Snackbar closed on its own } } @Override public void onShown(Snackbar snackbar) { ... } }); snackBar.show();
quelle
if (event != Snackbar.Callback.DISMISS_EVENT_ACTION)
stattdessen zu überprüfen, ob Ihre Entlassungslogik nicht ausgeführt wird, wenn der Benutzer manuell entlässt oder eine Snackbar von einer anderen aufeinanderfolgenden Snackbar entlassen wird.setCallback
ist jetzt veraltet undaddCallback
sollte verwendet werdenhttps://developer.android.com/reference/android/support/design/widget/BaseTransientBottomBar.html#addCallback(android.support.design.widget.BaseTransientBottomBar.BaseCallback )
quelle
Es gibt derzeit keine Möglichkeit, eine Benachrichtigung zu erhalten, wenn die Anzeige der Snackbar beendet ist.
In diesem Thread wird eine Problemumgehung basierend auf einem Timer für die Dauer der Snackbar-Anzeige erläutert. Die Snackbar in der Support-Bibliothek enthält OnDismissListener () nicht?
Ein Problem, das bei dieser Problemumgehung berücksichtigt werden muss, ist, dass die Snackbar-Dauer möglicherweise neu gestartet wird. Die Materialdesignspezifikation für Snackbar besagt, dass dies passieren wird, wenn ein nicht verwandter Dialog oder ein Popup angezeigt wird.
quelle
Derzeit können Sie es nicht erreichen.
Es wird kein Zuhörer angerufen, wenn die Snackbar verkleinert ist.
Der einfachste Weg, dies zu tun, besteht darin, den Datensatz vorübergehend an einer anderen Stelle (sogar in einer lokalen Variablen) zu speichern und ihn dann erneut einzufügen, wenn sie zufällig auf die Schaltfläche "Rückgängig" klicken.
quelle
snackbar.addCallback(new Snackbar.Callback() { public void onShown(Snackbar snackbar) { // on show } public void onDismissed(Snackbar snackbar, int event) { // on dismiss } });
quelle
Ich habe genau das gleiche Problem wie Sie. Meine Lösung ist ...
final Snackbar povrati_obrisani_unos = Snackbar.make (coordinatorLayout, "Ponisti brisanje", Snackbar.LENGTH_INDEFINITE) .addCallback (new Snackbar.Callback (){ @Override public void onDismissed(Snackbar transientBottomBar, int event) { super.onDismissed (transientBottomBar, event); if(event==DISMISS_EVENT_SWIPE){//here we detect if snackbar is swipped away and not cliked (which is undo in my case) Uri uriDelete = Uri.parse (obrisano.getImageuri ()); ContentResolver contentResolver = getContentResolver(); contentResolver.delete (uriDelete, null, null); Toast.makeText (MainActivity.this, "Ocitavanje i slika su trajno obrisani", Toast.LENGTH_SHORT).show (); }
Das ist alles, nicht Snackbar kopieren und einfügen. Aktion, die rückgängig gemacht wird. Möchte klar sein, wie ich hier nur kann.
Grüße Nenad
quelle
Dank @SergeyMilakov in Kotlin ist es:
@SuppressLint("WrongConstant") // Suppress an error when set duration. private fun showSnackbar() { val DURATION = 5000 Snackbar.make(view!!, "Remove item?"), DURATION).apply { setAction("Undo") { // Your action when a button is clicked. } addCallback(object : BaseTransientBottomBar.BaseCallback<Snackbar>() { /* override fun onShown(transientBottomBar: Snackbar?) { super.onShown(transientBottomBar) Timber.d("*** onShown") }*/ override fun onDismissed(transientBottomBar: Snackbar?, event: Int) { super.onDismissed(transientBottomBar, event) if (event != Snackbar.Callback.DISMISS_EVENT_ACTION) { // Your action when the Snackbar is closed and the button was not clicked. } } }) view.setBackgroundColor(ContextCompat.getColor(context, R.color.black)) setActionTextColor(ContextCompat.getColor(context, R.color.yellow)) show() } }
Beachten Sie, dass dies
Snackbar
angezeigt wird, auch wenn Sie zu anderen Bildschirmen wechseln (z. B. zurück). Vergessen Sie also nicht zu überprüfen, ob Sie auf dem rechten Bildschirm Aktionen ausführen.Wird
Snackbar
auch nach der Bildschirmdrehung nicht wiederhergestellt.quelle