Wie entlasse ich eine Snackbar mit ihrer eigenen Aktionsschaltfläche?

93

Die Android Design Support Library enthält jetzt Unterstützung für Snackbar.

Ich habe den folgenden Code verwendet, um einen zu erstellen:

Snackbar.make(findViewById(R.id.root_layout), result, Snackbar.LENGTH_LONG)
        .setAction("Dismiss", new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        }).show();

Die Snackbar kann durch Wischen entlassen werden. Ich möchte es jedoch auch mit seiner eigenen Aktionsschaltfläche (erstellt mit der Funktion setAction) schließen.

Es scheint jedoch keine Funktion verfügbar zu sein, die dies tun kann.

Asim
quelle
4
Als Hinweis für Leute, die hierher kommen, verstößt das Ausführen einer "Ablehnungs" -Aktion Snackbargegen die Google Material Design Guidelines .
Loyalar

Antworten:

145

Für Java

Die .makeMethode gibt ein SnackbarObjekt zurück. Speichern Sie eine Instanz dieses Objekts, indem Sie es erstellen final. Dann in die onClick()rufen .dismiss:

final Snackbar snackBar = Snackbar.make(findViewById(android.R.id.content), "Snackbar Message", Snackbar.LENGTH_LONG);

        snackBar.setAction("Action Message", new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Call your action method here
                snackBar.dismiss();
            }
        });
        snackBar.show();

Für Kotlin

        Snackbar.make(
            findViewById(android.R.id.content),
            "Snackbar Message",
            Snackbar.LENGTH_INDEFINITE
        ).setAction("Action Message") {
            // Call action functions here
        }.show()
EE66
quelle
2
Wenn ich dies in einem Koordinator-Layout mit einem FloatingActionButton mache, wird der FloatingActionButton nicht heruntergefahren.
Vinay W
59
Eine Snackbar wird standardmäßig geschlossen, wenn Sie auf die Aktion klicken. Das explizite Aufrufen der Entlassungsmethode ist nicht erforderlich.
Mark Buikema
9
@ MarkBuikema Diese Funktion wurde später hinzugefügt. Zum Zeitpunkt der Frage war das nicht das taubstumme Verhalten der Snackbar.
EE66
JFYI, die Aktion wird nicht angezeigt, wenn die OnClickListener isnull
crgarridos
Ab heute ruft dieser Code zweimal "entlassen" mit unterschiedlichem Ereigniswert auf, einen zum Klicken auf die Aktion und einen zum programmgesteuerten Aufrufen von "dissmiss ()".
Juan
53

Implementieren Sie eine Klickaktion und lassen Sie sie leer. Wenn Sie auf eine leere Klickaktion klicken, wird die Snackbar geschlossen.

Snackbar.make(coordinatorLayoutView, "Service Enabled", Snackbar.LENGTH_LONG)
    .setAction("DISMISS", new View.OnClickListener() {
        @Override
        public void onClick(View v) {
        }
    })
    .show();
Ali Zarei
quelle
Sie können nullals Listener übergehen , ohne eine tatsächliche Instanz erstellen zu müssen
ccpizza
11

Wenn Sie verwenden Snackbar.LENGTH_LONG, benötigen Sie keine Aktionsschaltfläche zum Entlassen, nach dem zweiten automatisch entlassen. Sie sollten diesen Code verwenden:

 Snackbar snackbar = Snackbar.make(relativeLayout, "Your Message", Snackbar.LENGTH_INDEFINITE);
            snackbar.setAction("dismiss", new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    snackbar.dismiss();
                }
            });

            snackbar.show();

Seien Sie vorsichtig in dieser Zeile :

Snackbar.LENGTH_INDEFINITE
hamed golbahar
quelle
5

Dies ist eine alte Frage, aber ich möchte nur meine eigenen Erfahrungen mit ähnlichen Funktionen in der Snackbar teilen. Wir haben also ein Design für unsere App, dass die Snackbar auf unbestimmte Zeit angezeigt werden soll und der Benutzer sie schließen kann. Es sollte jedoch keine Schaltfläche zum Ablehnen enthalten sein (Google empfiehlt ohnehin nicht, Aktionen in Snackbars zu schließen oder abzubrechen). Unsere Snackbar musste einfach durch Tippen entlassen werden.

Die einzige Lösung, die für uns funktioniert hat, war am Ende (ich verwende hier Retrolambda, aber es kann auch Standard View.OnClickListener verwendet werden):

final Snackbar snack = ... /* create proper snackbar as alway */
snack.getView().setOnClickListener(v -> snack.dismiss());

Beachten Sie den Aufruf von getView () in der Mitte.

Dariusz Wiechecki
quelle
Wo lesen Sie, dass "Google nicht empfiehlt, Aktionen in Snackbars zu schließen oder abzubrechen"? Ich würde gerne den Grund lesen ...
JoseF
@JoseF Bitte überprüfen Sie den ersten Kommentar unter der Frage selbst;) Er befindet sich in den Richtlinien für Materialdesign : material.io/guidelines/components/… ("0-1 Aktionen, nicht entlassen oder stornieren")
Dariusz Wiechecki
3

Die Snackbar (von 'com.android.support:design:23.2.1' ) unterstützt viele Arten von Entlassungsaktionen. Sie können einen einfachen Filter mithilfe eines Ereignisses erstellen , z. B. in diesem Beispiel:

Snackbar.make(view, wornMessage, Snackbar.LENGTH_LONG).setActionTextColor(context.getResources().getColor(R.color.primary))
    .setCallback(new Snackbar.Callback() {
        @Override
        public void onShown(Snackbar snackbar) {
            super.onShown(snackbar);
        // when snackbar is showing
        }

        @Override
        public void onDismissed(Snackbar snackbar, int event) {
            super.onDismissed(snackbar, event);
            if (event != DISMISS_EVENT_ACTION) {
               //will be true if user not click on Action button (for example: manual dismiss, dismiss by swipe
            }
        }
    })
    .setAction("Undo, view1 -> {
        // if user click on Action button
}).show();

Entlassungsarten von Snackbar:

/** Indicates that the Snackbar was dismissed via a swipe.*/
public static final int DISMISS_EVENT_SWIPE = 0;
/** Indicates that the Snackbar was dismissed via an action click.*/
public static final int DISMISS_EVENT_ACTION = 1;
/** Indicates that the Snackbar was dismissed via a timeout.*/
public static final int DISMISS_EVENT_TIMEOUT = 2;
/** Indicates that the Snackbar was dismissed via a call to {@link #dismiss()}.*/
public static final int DISMISS_EVENT_MANUAL = 3;
/** Indicates that the Snackbar was dismissed from a new Snackbar being shown.*/
public static final int DISMISS_EVENT_CONSECUTIVE = 4;

PS Im Beispielcode verwendete Lambda-Ausdrücke (von RetroLambda)

a.black13
quelle
Die Frage bezieht sich nicht auf einen Entlassungshelfer. Die Frage ist, wie man beim Klicken auf die Schaltfläche schließt.
Der unglaubliche
2

Ich hatte das gleiche Problem. Als ich .dismiss () verwendete, sahen die Animationen anders aus und es gab zwei Probleme:

  1. FAB geht nicht wieder runter
  2. Die SnackBar selbst rutscht nicht wie bei einem Klick nach unten

Beim Betrachten des ursprünglichen Android-Quellcodes für Snackbar habe ich die folgende Lösung gefunden:

View snackbarView = snackbar.getView();
Button snackbarActionButton = (Button) snackbarView.findViewById(android.support.design.R.id.snackbar_action);
//snackbarActionButton.setSoundEffectsEnabled(false); // might be considered in order not to have a confusing sound because nothing was clicked by the user

Dann würde ich den .performClick auf dem SnackBarActionButton aufrufen

snackBarActionButton.performClick();

Link zum Android-Quellcode für Snackbar: https://android.googlesource.com/platform/frameworks/support/+/refs/heads/master/design/src/android/support/design/widget/Snackbar.java

kiting_and_coding
quelle
Macht für mich keinen Sinn. Warum sollten Sie performClick () aufrufen, wenn Sie tatsächlich auf eine Schaltfläche klicken? Das scheint Unsinn zu sein.
Der unglaubliche