Как закрыть Snackbar с помощью собственной кнопки действия?

Библиотека поддержки дизайна 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).

Однако, похоже, нет какой-либо доступной функции, которая могла бы это сделать.


person Asim    schedule 09.06.2015    source источник
comment
Обратите внимание на то, что действие "Отклонить" на Snackbar противоречит Рекомендации Google по дизайну материалов.   -  person Loyalar    schedule 08.08.2016
comment
В частности: material.io/design/components/snackbars.html#usage.   -  person Brian Stewart    schedule 12.02.2019


Ответы (6)


Для 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()
person EE66    schedule 09.06.2015
comment
если я сделаю это в макете координатора с помощью FloatingActionButton, FloatingActionButton не сработает. - person Vinay W; 01.07.2015
comment
По умолчанию закусочная закрывается при нажатии на действие. В явном вызове метода увольнения нет необходимости. - person Mark Buikema; 02.11.2015
comment
@MarkBuikema эта функция была добавлена ​​позже. Во время вопроса это не было глухим поведением закусочной. - person EE66; 02.11.2015
comment
JFYI, действие не будет отображаться, если OnClickListener равно null - person crgarridos; 12.07.2018
comment
На сегодняшний день этот код будет вызывать отклонение дважды с разными значениями события, один для щелчка по действию, а другой для программного вызова dismiss (). - person Juan; 06.04.2019

Реализуйте действие щелчка и оставьте его пустым. Нажатие на пустое действие щелчка приведет к закрытию закусочной.

Snackbar.make(coordinatorLayoutView, "Service Enabled", Snackbar.LENGTH_LONG)
                        .setAction("DISMISS", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                            }
                        })
                        .show();
person Ali Zarei    schedule 20.09.2015
comment
вы можете передать null для слушателя, нет необходимости создавать фактический экземпляр - person ccpizza; 15.06.2020

Когда вы используете 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
person hamed golbahar    schedule 09.08.2016

Это старый вопрос, но я просто хочу поделиться своим опытом использования аналогичной функции на Snackbar. Итак, у нас есть дизайн для нашего приложения, в котором закусочная должна отображаться на неопределенный срок, и пользователь должен иметь возможность закрыть ее ... но внутри нее не должно быть кнопки DISMISS (Google в любом случае не рекомендует отклонять или отменять действия внутри закусочных). Наша закусочная нужно было закрыть, просто нажав на нее.

Единственное решение, сработавшее для нас, было в итоге (я использую здесь retrolambda, но можно использовать и стандартный View.OnClickListener):

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

Обратите внимание на вызов getView () посередине.

person Dariusz Wiechecki    schedule 17.02.2017
comment
Где вы читаете, что Google не рекомендует закрывать или отменять действия в Snackbars? Хочу прочесть причину .... - person JoseF; 14.09.2017
comment
@JoseF Пожалуйста, проверьте первый комментарий под самим вопросом;) Он находится в руководстве по материальному дизайну: material.io/guidelines/components/ (0–1 действие, без отклонения или отмены) - person Dariusz Wiechecki; 15.09.2017
comment
Этот ответ уникален тем, что дает возможность отклонить снекбар, для которого установлено значение «LENGTH_INDEFINITE» (чтобы у пользователя было время его прочитать), без необходимости запускать какое-либо действие, которое запускает кнопка действия. Я использую Snackbar, чтобы уведомить своих игроков о том, что обновление было загружено, и перезапустить, если они хотят, чтобы оно было реализовано. Если они не готовы к перезапуску, мне нужен способ закрыть его, не нажимая кнопку действия. Закуски на моих тестовых устройствах не закрываются одним движением. Этот код отклоняет его одним касанием за пределами кнопки действия, что, на мой взгляд, должно быть поведением по умолчанию. - person Androidcoder; 01.11.2020

Панель закусок (от '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();

Типы увольнения 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;

P.S. В примере кода используются лямбда-выражения (от RetroLambda)

person a.black13    schedule 09.04.2016
comment
Вопрос не в увольнении. Вопрос в том, как закрыть по нажатию кнопки. - person The incredible Jan; 01.03.2018

У меня такая же проблема. Когда я использовал .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 < / а>

person kiting_and_coding    schedule 06.03.2016
comment
Для меня это не имеет никакого смысла. Зачем вам вызывать performClick (), если вы действительно нажимаете кнопку? Кажется, это ерунда. - person The incredible Jan; 01.03.2018