Как исправить высоту и положение Snackbar?

В библиотеке поддержки Android 24.1.1 Snackbar работал нормально:

до

Затем, начиная с библиотеки поддержки Android 24.2.0, Snackbar начал вести себя следующим образом:

после

В библиотеке история изменений , есть следующее утверждение:

Изменения в поведении: Snackbar теперь отображается за панелью навигации, если строка состояния полупрозрачна.

Но дело в том, что мое приложение работает в полноэкранном режиме, и в нем нет панели навигации или строки состояния. Как я могу это исправить?


person thiagolr    schedule 23.12.2016    source источник


Ответы (7)


Посмотрите этот ответ https://stackoverflow.com/a/42180120/2550743 и просто замените

 params.setMargins(params.leftMargin,
            params.topMargin,
            params.rightMargin,
            params.bottomMargin + ScreenUtils.getNavigationBarHeight(activity));

to

 params.setMargins(params.leftMargin,
            params.topMargin,
            params.rightMargin,
            params.bottomMargin - ScreenUtils.getNavigationBarHeight(activity));
person Alexandr Larin    schedule 11.02.2017

Недавно я решил эту проблему, вычтя высоту панели навигации из нижнего поля представления Snackbar.

Для начала нам нужна высота панели навигации. Я нашел код для этого в ответе, отмеченном здесь как правильный: Как ДЕЙСТВИТЕЛЬНО получить высоту панели навигации в Android

Затем используйте следующий код для настройки нижнего поля Snackbar:

final Snackbar snackbar = Snackbar.make(findViewById(R.id.fullscreen_content),
                message, Snackbar.LENGTH_LONG);

View snackbarView = snackbar.getView();

// Adjust Snackbar height for fullscreen immersive mode
int navbarHeight = getNavigationBarSize(this).y;

CoordinatorLayout.LayoutParams parentParams = (CoordinatorLayout.LayoutParams) snackbarView.getLayoutParams();
    parentParams.setMargins(0, 0, 0, 0 - navbarHeight);
    snackbarView.setLayoutParams(parentParams);

snackbar.show();

Обратите внимание, что я использовал LayoutParams из CoordinatorLayout. Вам следует заменить CoordinatorLayout тем родительским типом макета, который вы передали в свою Snackbar.make() функцию (в моем случае R.id.fullscreen_content является CoordinatorLayout). Преимущество использования CoordinatorLayout заключается в том, что он позволяет отклонять Snackbars, проводя пальцем по экрану как стандартное поведение.

person maxarmour    schedule 02.05.2017
comment
You should replace CoordinatorLayout with whichever parent layout type you have passed in to your Snackbar.make() function Вы также можете просто использовать общий родительский MarginLayoutParams, когда просто хотите отредактировать поля. - person avalancha; 09.12.2020

Принятый ответ работал со старыми версиями библиотек поддержки, где Snackbar был просто прямоугольным представлением. На самом деле при изменении поля на отрицательное значение просто отсекается нижняя часть SnackbarLayout (макет контейнера Snackbar), поэтому более новые версии, в которых Snackbar имеет закругленные углы, плохо смотрятся с этим решением.

Подсказка находится здесь в коде: https://github.com/material-components/material-components-android/blob/cd59e98f7e2185ddb075ff0fc91f29765d562968/lib/java/com/google/Translation/materialBomnsackbar/snackbar/snackbar/.java#L272

На самом деле происходит то, что к контейнеру добавляется заполнение, поэтому способ правильно исправить высоту - это сбросить заполнение до правильного значения. Вы можете сделать это, добавив дополнительный OnApplyWindowInsetsListener, например следующий (установка нижнего отступа таким же, как верхний, заставит Snackbar выглядеть нормально):

ViewCompat.setOnApplyWindowInsetsListener(snackbar.view) { v, insets ->
    v.setPadding(v.paddingLeft, v.paddingTop, v.paddingRight, v.paddingTop)
    insets
}

Затем, поскольку Snackbar теперь будет иметь правильную высоту, но появится за полупрозрачной панелью навигации, вы можете увеличить нижнее поле на значение нижней вставки:

ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets ->
    v.setPadding(v.paddingLeft, v.paddingTop, v.paddingRight, v.paddingTop)

    val params = v.layoutParams as ViewGroup.MarginLayoutParams
    params.updateMargins(
        params.leftMargin,
        params.topMargin,
        params.rightMargin,
        params.bottomMargin + insets.systemWindowInsetBottom
    )
    v.layoutParams = params

    insets
}

Фактически это было исправлено в альфа-библиотеках Material 1.1.0 (теперь библиотека меняет поля, а не отступы), но они, вероятно, еще не готовы к производственному использованию.

person Philio    schedule 04.07.2019

Это 2020 год, и я не знаю, связано ли это, но у меня есть моя закусочная с некоторыми отступами внизу при использовании навигации с помощью жестов Android 10. В моем случае ничего из вышеперечисленного не работает. Я наконец исправил это с помощью супер простой строчки:

val snackbar = Snackbar.make(view, message, duration)
snackbar.isGestureInsetBottomIgnored = true // here
snackbar.show()

Надеюсь, это поможет.

person Alex Do    schedule 17.02.2020

Другой способ был бы

Snackbar snackbar = Snackbar.make(view, ...);
View snackBarView = snackbar.getView();

ViewCompat.setFitsSystemWindows(snackBarView, false);
ViewCompat.setOnApplyWindowInsetsListener(snackBarView, null);

Это отключит дополнительные нижние отступы в иммерсивном режиме.

person vokilam    schedule 01.08.2019
comment
со мной это не сработало. Кроме того, ViewCompat.setFitsSystemWindows обесценен. - person Aliton Oliveira; 30.05.2020
comment
Спасибо, это работает! Я немного изменил код. View snackbarView = snackbar.getView (); снэкбарвиев.setFitsSystemWindows (ложь); снэкбарвиев.setOnApplyWindowInsetsListener (нуль); - person Sinan Ceylan; 09.07.2020

Используйте это в своей закусочной,

FrameLayout.LayoutParams params =(FrameLayout.LayoutParams)view.getLayoutParams();
    params.gravity = Gravity.BOTTOM;
person Ranjan    schedule 23.12.2016
comment
Вы используете view.requestLayout (); после этой строки? - person Ranjan; 21.03.2018

Если все, что вас волнует, это высота, а не положение, приготовьтесь к тому, что ваш мозг взорвется! : D

Настройте содержимое закусочной на:

Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Text(
            'Your SnackBar message',
          ),
          SizedBox(
            height: 70, // Your desired height
          )
        ],
      ))
person Samer    schedule 29.07.2019