Skip to content

Особенности Snackbar

Roman edited this page Mar 26, 2019 · 5 revisions

Кратко:

Стиль Widget.MaterialComponents.Snackbar - в виде плавающей панели

<!-- Стиль по умолчанию -->
<item name="snackbarStyle">@style/Widget.MaterialComponents.Snackbar</item>
<!-- Цвет текста -->
<item name="colorSurface">@color/white</item> 
<!-- Цвет фона всплывающей панели -->
<item name="colorOnSurface">@color/black</item>

Важно Если в colorOnSurface установить color selector то всё перестаёт работать, отборажается не тёмная, а светлая тема для Snackbar. Долго не мог понять откуда баг, потом установил в colorOnSurface одинарный цвет и всё заработало

Стиль Widget.MaterialComponents.Snackbar.FullWidth - в виде выезжающей снизу плашки Стиль Widget.Design.Snackbar ведёт себя аналогично

<!-- Стиль по умолчанию -->
<item name="snackbarStyle">@style/Widget.MaterialComponents.Snackbar</item>
<!-- Цвет текста -->
<item name="colorSurface">@color/white</item> 
<!-- Цвет фона берётся из background темы - всегда тёмно серый  -->

Особенности Material Snackbar

Стандартные сили для Snackbar

  <style name="TextAppearance.Design.Snackbar.Message" parent="android:TextAppearance">
    <item name="android:textSize">@dimen/design_snackbar_text_size</item>
    <item name="android:textColor">?android:textColorPrimary</item>
  </style>

  <style name="Widget.Design.Snackbar" parent="android:Widget">
    <item name="android:minWidth">@dimen/design_snackbar_min_width</item>
    <item name="android:maxWidth">@dimen/design_snackbar_max_width</item>
    <item name="android:background">@drawable/design_snackbar_background</item>
    <item name="android:paddingLeft">@dimen/design_snackbar_padding_horizontal</item>
    <item name="android:paddingRight">@dimen/design_snackbar_padding_horizontal</item>
    <item name="elevation">@dimen/design_snackbar_elevation</item>
    <item name="maxActionInlineWidth">@dimen/design_snackbar_action_inline_max_width</item>
    <item name="animationMode">slide</item>
    <item name="actionTextColorAlpha">@dimen/design_snackbar_action_text_color_alpha</item>
  </style>

  <style name="Widget.MaterialComponents.Snackbar" parent="Widget.Design.Snackbar">
    <!-- Null out the background here so the programmatically defined default Snackbar background
         will be used, which supports the Material color theming attributes. -->
    <item name="android:background">@null</item>
    <item name="android:layout_margin">@dimen/mtrl_snackbar_margin</item>
    <item name="animationMode">fade</item>
    <item name="backgroundOverlayColorAlpha">@dimen/mtrl_snackbar_background_overlay_color_alpha</item>
    <item name="actionTextColorAlpha">@dimen/mtrl_snackbar_action_text_color_alpha</item>
  </style>

  <style name="Widget.MaterialComponents.Snackbar.FullWidth" parent="Widget.Design.Snackbar">
    <item name="backgroundOverlayColorAlpha">@dimen/mtrl_snackbar_background_overlay_color_alpha</item>
    <item name="actionTextColorAlpha">@dimen/mtrl_snackbar_action_text_color_alpha</item>
  </style>

Атрибуты в теме, откуда берутся стили для Snackbar

snackbarStyle snackbarButtonStyle

В коде проекта выбирается разный layout для отображения SnackbarContentLayout в зависимости установлен ли атрибут в теме snackbarButtonStyle

hasSnackbarButtonStyleAttr(parent.getContext())
                    ? R.layout.mtrl_layout_snackbar_include
                    : R.layout.design_layout_snackbar_include

mtrl_layout_snackbar_include

<view
  xmlns:android="http://schemas.android.com/apk/res/android"
  class="com.google.android.material.snackbar.SnackbarContentLayout"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_gravity="bottom"
  android:theme="@style/ThemeOverlay.AppCompat.Dark">

  <TextView
    android:id="@+id/snackbar_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:layout_gravity="center_vertical|left|start"
    android:paddingTop="@dimen/design_snackbar_padding_vertical"
    android:paddingBottom="@dimen/design_snackbar_padding_vertical"
    android:paddingLeft="@dimen/design_snackbar_padding_horizontal"
    android:paddingRight="@dimen/design_snackbar_padding_horizontal"
    android:alpha="@dimen/mtrl_emphasis_high_type"
    android:ellipsize="end"
    android:maxLines="@integer/design_snackbar_text_max_lines"
    android:textAlignment="viewStart"
    android:textAppearance="?attr/textAppearanceBody2"
    android:textColor="?attr/colorSurface"/>

  <Button
    android:id="@+id/snackbar_action"
    style="?attr/snackbarButtonStyle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="@dimen/design_snackbar_extra_spacing_horizontal"
    android:layout_marginLeft="@dimen/design_snackbar_extra_spacing_horizontal"
    android:layout_gravity="center_vertical|right|end"
    android:minWidth="48dp"
    android:visibility="gone"/>

</view>

design_layout_snackbar_include

<view
    xmlns:android="http://schemas.android.com/apk/res/android"
    class="com.google.android.material.snackbar.SnackbarContentLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:theme="@style/ThemeOverlay.AppCompat.Dark">

  <TextView
      android:id="@+id/snackbar_text"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:layout_gravity="center_vertical|left|start"
      android:paddingTop="@dimen/design_snackbar_padding_vertical"
      android:paddingBottom="@dimen/design_snackbar_padding_vertical"
      android:paddingLeft="@dimen/design_snackbar_padding_horizontal"
      android:paddingRight="@dimen/design_snackbar_padding_horizontal"
      android:ellipsize="end"
      android:maxLines="@integer/design_snackbar_text_max_lines"
      android:textAlignment="viewStart"
      android:textAppearance="@style/TextAppearance.Design.Snackbar.Message"/>

  <Button
      android:id="@+id/snackbar_action"
      style="?attr/borderlessButtonStyle"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginStart="@dimen/design_snackbar_extra_spacing_horizontal"
      android:layout_marginLeft="@dimen/design_snackbar_extra_spacing_horizontal"
      android:layout_gravity="center_vertical|right|end"
      android:minWidth="48dp"
      android:textColor="?attr/colorAccent"
      android:visibility="gone"/>

</view>

Видим, что тема для самой плашки Snackbar используется ThemeOverlay.AppCompat.Dark - тёмная тема. Для цвета текста используется параметр colorSurface (если snackbarButtonStyle != @null) либо android:textColorPrimary

Важно Почемуто если colorOnSurface установить color selector то всё перестаёт работать, отборажается не тёмная, а светлая тема для Snackbar. Долго не мог понять откуда баг, потом установил в colorOnSurface одинарный цвет и всё заработало

  <item name="colorSurface">@color/white</item>
  <item name="colorOnSurface">@color/black</item>
Clone this wiki locally