Як відхилити Snackbar за допомогою власної кнопки Action?


93

Бібліотека підтримки дизайну Android тепер включає підтримку Snackbar.

Я створив такий код:

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

            }
        }).show();

Снек-бар можна відхилити, провевши пальцем. Однак я також хочу відхилити його за допомогою власної кнопки дії (створеної за допомогою функції setAction).

Однак, здається, немає жодної доступної функції, яка може це зробити.


4
Як примітка для людей, які приїжджають сюди, проведення дії „Відхилити” на веб-сайті Snackbarсуперечить Правилам Google щодо дизайну матеріалів .
Лоялар

Відповіді:


145

Для Java

.makeМетод повертає Snackbarоб'єкт. Збережіть екземпляр цього об’єкта, зробивши його final. Потім у onClick()виклику .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();

Для Котліна

        Snackbar.make(
            findViewById(android.R.id.content),
            "Snackbar Message",
            Snackbar.LENGTH_INDEFINITE
        ).setAction("Action Message") {
            // Call action functions here
        }.show()

2
якщо я роблю це в макеті координатора за допомогою FloatingActionButton, FloatingActionButton не падає.
Vinay W

60
Снек-бар за замовчуванням відхиляється при натисканні на дію. Явний виклик методу звільнення непотрібний.
Марк Буйкема

9
@MarkBuikema цю функцію було додано пізніше. На момент запитання це не було глухою поведінкою закусочної.
EE66,

JFYI, дія не буде показана, якщо OnClickListenerєnull
crgarridos

На сьогоднішній день цей код буде викликати відхилення двічі з різним значенням події, один для натискання на дію та інший для програмного виклику DISMISS ().
Хуан

52

Здійсніть дію клацання та залиште її порожньою. Натискання на порожній клік призведе до вимкнення панелі перекусів.

Snackbar.make(coordinatorLayoutView, "Service Enabled", Snackbar.LENGTH_LONG)
    .setAction("DISMISS", new View.OnClickListener() {
        @Override
        public void onClick(View v) {
        }
    })
    .show();

ви можете передати nullслухача, не потрібно створювати фактичний екземпляр
ccpizza

11

Коли ви використовуєте, Snackbar.LENGTH_LONGвам не потрібна кнопка дії для звільнення, після другої автоматичного звільнення. Ви повинні використовувати цей код:

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

Будьте обережні в цьому рядку :

Snackbar.LENGTH_INDEFINITE

5

Це старе запитання, але я просто хочу поділитися власним досвідом щодо подібної функції на Snackbar. Отже, ми отримали дизайн для нашого додатку, що закусочну слід показувати нескінченно, а користувач повинен мати можливість її відхилити .. але в ній не повинно бути кнопки DISMISS (Google все одно не рекомендує виконувати дії «Відхилити» чи «Скасувати»). Нашу закусочну потрібно було звільнити, просто натиснувши на неї.

Єдиним рішенням, яке працювало для нас, було врешті-решт (я використовую тут retrolambda, але також міг бути використаний стандартний View.OnClickListener):

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

Зверніть увагу на виклик getView () посередині.


Де ви читаєте, що "Google не рекомендує відхиляти чи скасовувати дії всередині закусочних"? Я хотів би прочитати причину ....
JoseF

@JoseF Будь ласка, ознайомтесь із першим коментарем під самим запитанням;) Це в Директиві щодо матеріального дизайну: material.io/guidelines/components/… ("0-1 дії, не відхиляти та не скасовувати")
Даріуш Вєчецький,

3

Снек-бар (із 'com.android.support:design:23.2.1' ) підтримує багато типів дій із відхиленням. Ви можете створити простий фільтр, використовуючи подію , як у цьому прикладі:

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

Типи відмови від закусочної:

/** 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 У зразку коду використані лямбда-вирази (від RetroLambda)


Питання не в обробнику звільнень. Питання в тому, як відхилити натискання кнопки.
Неймовірний

2

У мене була та сама проблема. Коли я використовував .dismiss (), анімація виглядала по-різному, і було дві проблеми:

  1. FAB знову не падає
  2. сам SnackBar не ковзає вниз, як при натисканні

Розглядаючи оригінальний вихідний код Android для Snackbar, я знайшов таке рішення:

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

Потім я би зателефонував до .performClick на snackBarActionButton

snackBarActionButton.performClick();

Посилання на вихідний код Android для Snackbar: https://android.googlesource.com/platform/frameworks/support/+/refs/heads/master/design/src/android/support/design/widget/Snackbar.java


Для мене це не має ніякого сенсу. Чому ви повинні викликати perforClick (), якщо ви насправді натискаєте кнопку? Це, здається, нісенітниця.
Неймовірний
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.