Закусочная с CoordinatorLayout отключить отключение

я пользуюсь поддержкой

  • ПлавающаяКнопкаДействия
  • Снэк-бар
  • КоординаторМакет

Мне нужен CoordinatorLayout, чтобы при отображении SnackBar FloatingActionButton перемещался вверх, освобождая место для Snackbar. Для лучшего понимания посмотрите это видео.

Я использую SnackBar для двойного возврата, чтобы выйти из приложения, но SnackBar можно закрыть.

Есть ли способ отключить закрытие SnackBar?

Snackbar snackbar = Snackbar.make(view, R.string.press_back_again_to_exit, Snackbar.LENGTH_SHORT);
snackbar.setAction(R.string.ok, new View.OnClickListener() {
    @Override
    public void onClick(View v)
    {

    }
});
snackbar.setActionTextColor(getResources().getColor(R.color.white));

View view = snackbar.getView();
view.setBackgroundColor(getResources().getColor(R.color.orange_warning));

snackbar.show();

Макет

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        xmlns:sothree="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:fitsSystemWindows="true">

        <com.sothree.slidinguppanel.SlidingUpPanelLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="bottom"
            sothree:umanoFadeColor="@android:color/transparent"
            sothree:umanoPanelHeight="100dp"
            sothree:umanoShadowHeight="4dp">

            <!-- Toolbar and main content -->
            <LinearLayout
                android:id="@+id/toolbar_and_content"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <include layout="@layout/toolbar"/>

                <!-- Your content layout -->
                <FrameLayout
                    android:id="@+id/content_frame"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"/>

            </LinearLayout>

            <!-- Sliding up panel layout -->
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/darker_grey"
                android:orientation="vertical">

                ...

            </LinearLayout>

        </com.sothree.slidinguppanel.SlidingUpPanelLayout>


        <!-- Navigation drawer -->
        <ExpandableListView
            android:id="@+id/lv_left_drawer"
            android:layout_width="280dp"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:background="@color/white"
            android:childDivider="@android:color/transparent"
            android:clickable="true"
            android:divider="@color/divider_color"
            android:dividerHeight="0.6dp"
            android:fadeScrollbars="true"
            android:groupIndicator="@null"
            android:listSelector="@drawable/button_drawer_child_selector"
            android:scrollbarSize="0dp"/>

    </android.support.v4.widget.DrawerLayout>

    <android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right|bottom"
        android:layout_marginBottom="@dimen/floating_action_button_margin"
        android:layout_marginRight="@dimen/floating_action_button_margin"
        android:src="@drawable/ic_add"
        android:visibility="invisible"
        app:backgroundTint="@color/orange"
        app:borderWidth="0dp"
        app:elevation="6dp"
        app:fabSize="normal"/>

</android.support.design.widget.CoordinatorLayout>

P.S.

Мне известно об этой библиотеке GitHub, которая имеет эту функциональность, но есть ли "родной" способ сделать Это?


person Marko    schedule 24.08.2015    source источник
comment
я думаю, что нет никакого способа   -  person Archit Jain    schedule 24.08.2015
comment
Я использую SnackBar для двойного возврата при выходе из приложения — вы идете против шаблонов пользовательского интерфейса платформы. SnackBars предназначены для небольшой обратной связи, а не для того, чтобы просить пользователя о действии (например, я предполагаю, что вы пытаетесь сделать, когда пользователь дважды нажимает назад)   -  person user    schedule 24.08.2015
comment
@Luksprog Я знаю об этом, того же можно добиться с тостами или гренками, но в основном это то же самое, SnackBar просто выглядит лучше. Я лично не сторонник двойного возврата на выход, но, к сожалению, это не мне решать.   -  person Marko    schedule 24.08.2015
comment
Проверьте мой ответ.....stackoverflow.com/a/35576829/1881527   -  person Melbourne Lopes    schedule 23.02.2016


Ответы (5)


Вы можете изменить продолжительность показа Snackbar. Это будет похоже на отключение увольнения.

int     LENGTH_INDEFINITE   Show the Snackbar indefinitely. 

Проверьте документы.

если это не работает. Для этого есть только один способ: реализовать свою пользовательскую закусочную и переопределить метод dismiss() и при этом ничего не делать. :) Так как dismiss() является общедоступным API.

person theJango    schedule 25.08.2015
comment
Не работает, SnackBar по-прежнему закрывается и остается там навсегда :) - person Marko; 25.08.2015
comment
[уволить или остаться навсегда] не могли бы вы немного объяснить. Это кажется противоречивым ;) - person theJango; 25.08.2015
comment
Если я установлю LENGTH_INDEFINITE, SnackBar не исчезнет через некоторое время... (имеет смысл), но я все равно могу его закрыть (проведите пальцем вправо, и он исчезнет). - person Marko; 25.08.2015
comment
@Marko: проверьте отредактированный ответ. Я знаю, что это бревенчатый способ, но это выполнимо. - person theJango; 25.08.2015
comment
@theJango Это не так .. хотя Snackbar не является классом final, его единственным конструктором является private, что фактически делает его final - person Ace; 17.02.2021

Snackbar теперь имеет фактическую поддержку отключения смахивания для закрытия с помощью метода setBehavior. Самое замечательное здесь то, что раньше вы всегда теряли некоторые модели поведения, которые теперь сохранились. Вы также можете использовать Snackbar.LENGTH_INDEFINITE

Обратите внимание, что пакет перемещен, поэтому вам необходимо импортировать «новый» Snackbar. в упаковке закусочной.

Snackbar.make(view, stringId, Snackbar.LENGTH_INDEFINITE)
    .setBehavior(new NoSwipeBehavior())
    .show();

class NoSwipeBehavior extends BaseTransientBottomBar.Behavior {

    @Override
    public boolean canSwipeDismissView(View child) {
      return false;
    }
}
person MinceMan    schedule 16.05.2018

Ответа только на использование LENGTH_INDEFINITE недостаточно.

Его нельзя закрыть, только если Snackbar не является дочерним элементом CoordinatorLayout. Когда это ребенок, вы все равно можете смахнуть SnackBar.

Что вы можете сделать в этом случае, так это прислушаться к исчезновению экрана и просто повторно отобразить Snackbar.

public void showAnnoyingSnackBar(View root, String text) {
    Snackbar.make(root, text, Snackbar.LENGTH_INDEFINITE)
        .setCallback(new Snackbar.Callback() {
            @Override public void onDismissed(Snackbar snackbar, int event) {
                // recursively call this method again when the snackbar was dismissed through a swipe
                if (event == DISMISS_EVENT_SWIPE) showAnnoyingSnackBar(root, text);
            }
        })
        .show();
}
person Paul Woitaschek    schedule 02.04.2016

Я заметил, что при вызове метода show() SnackbarLayout еще не полностью инициализирован.

Чтобы заблокировать отклонение, мы должны очистить поведение после инициализации SnackbarLayout. лучше всего это сделать, например, в OnPreDrawListener в SnackbarLayout.

final Snackbar snack = Snackbar.make(getView(), "I can't be dissmiss", Snackbar.LENGTH_INDEFINITE);
    snack.show();
    snack.getView().getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        @Override
        public boolean onPreDraw() {
            snack.getView().getViewTreeObserver().removeOnPreDrawListener(this);
                ((CoordinatorLayout.LayoutParams) snack.getView().getLayoutParams()).setBehavior(null);
                return true;
            }
        });
person TomMannson    schedule 01.04.2016

Мне удалось отключить закусочные, которые можно смахнуть вбок, чтобы закрыть, с помощью следующего хака (после вызова закусочной панели.show())

((android.support.design.widget.CoordinatorLayout.LayoutParams) snackbar.getView().getLayoutParams()).setBehavior(null);
person allanman    schedule 02.12.2015
comment
Офигенно, надо попробовать. Спасибо за Ваш ответ! - person Marko; 02.12.2015
comment
Это не работает для меня. Snackbar snackbar = Snackbar.make(this.rootView, "Blah", Snackbar.LENGTH_SHORT); snackbar.show();((CoordinatorLayout.LayoutParams) snackbar.getView().getLayoutParams()).setBehavior(null); - person Jared Burrows; 16.01.2016