Style SnackBar in theme app

20,719

Solution 1

With the Material Components Library you can globally change the snackbar style in your app theme:

<style name="AppTheme" parent="Theme.MaterialComponents.*">
    <!-- Style to use for Snackbars in this theme. -->
    <item name="snackbarStyle">@style/Widget.MaterialComponents.Snackbar</item>
    <!-- Style to use for action button within a Snackbar in this theme. -->
    <item name="snackbarButtonStyle">@style/Widget.MaterialComponents.Button.TextButton.Snackbar</item>
    <!-- Style to use for message text within a Snackbar in this theme. -->
    <item name="snackbarTextViewStyle">@style/Widget.MaterialComponents.Snackbar.TextView</item>
    ....
</style>

Note:

  • snackbarStyle and snackbarButtonStyle require the version 1.1.0
  • snackbarTextViewStyle requires the version 1.2.0.

For example:

  <style name="snackbar_style" parent="@style/Widget.MaterialComponents.Snackbar">
    <item name="android:layout_margin">32dp</item>
  </style>

  <style name="snackbar_button" parent="@style/Widget.MaterialComponents.Button.TextButton.Snackbar">
      <item name="backgroundTint">@color/secondaryLightColor</item>
      <item name="android:textColor">@color/primaryDarkColor</item>
  </style>

  <style name="snackbar_text" parent="@style/Widget.MaterialComponents.Snackbar.TextView">
    <item name="android:textColor">@color/secondaryLightColor</item>
  </style>

enter image description here

It is just an example how to change also the parent style for the action button. You can use for example a standard Widget.MaterialComponents.Button:

  <style name="snackbar_button" parent="@style/Widget.MaterialComponents.Button">
      <item name="backgroundTint">@color/secondaryLightColor</item>
      <item name="android:textColor">@color/primaryDarkColor</item>
  </style>

To change the background color of the SnackBar you can use:

<style name="snackbar_style" parent="@style/Widget.MaterialComponents.Snackbar">
    <!-- using backgroundTint the alpha layer is ignored -->
    <item name="backgroundTint">@color/....</item>
</style>

Or if you prefer:

   <style name="MySnackbar" parent="@style/Widget.MaterialComponents.Snackbar">
        <item name="materialThemeOverlay">@style/snackbar_overlay</item>
        <!-- If you want to avoid the alpha level for the color that is overlaid on top of the background color-->
        <item name="backgroundOverlayColorAlpha">1.0</item>
    </style>
    <style name="snackbar_overlay">
        <item name="colorOnSurface">....</item>
    </style>

Solution 2

you need this: tools:override="true"

<resources xmlns:tools="http://schemas.android.com/tools">
    <style name="TextAppearance.Design.Snackbar.Message" parent="android:TextAppearance" tools:override="true">
        <item name="android:textColor">@color/text</item>
        <item name="android:textSize">50sp</item>
    </style>
</resources>

Solution 3

Refer to this link for more information:

// create instance

Snackbar snackbar = Snackbar.make(view, text, duration);

// set action button color

snackbar.setActionTextColor(getResources().getColor(R.color.indigo));

// get snackbar view

View snackbarView = snackbar.getView();

// change snackbar text color

int snackbarTextId = android.support.design.R.id.snackbar_text;
TextView textView = (TextView)snackbarView.findViewById(snackbarTextId);
textView.setTextColor(getResources().getColor(R.color.indigo));

// change snackbar background

snackbarView.setBackgroundColor(Color.MAGENTA);

Solution 4

Thanks to shadowsheep I wrote these styles with Material Components. I also removed margins. You can compile his app to research Snackbar.

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>

    <!-- Snackbar -->
    <item name="snackbarStyle">@style/MaterialSnackbarTheme</item>
    <item name="snackbarButtonStyle">@style/MaterialSnackbarTextButtonTheme</item>
    <item name="snackbarTextViewStyle">@style/MaterialSnackbarTextViewTheme</item>
</style>

<style name="MaterialSnackbarTheme" parent="@style/Widget.MaterialComponents.Snackbar">
    <!-- <item name="backgroundTint">#00cc77</item>-->
    <!-- <item name="android:background">@drawable/snackbar_background</item>-->
    <item name="android:background">#00cc77</item>
    <item name="cornerRadius">0dp</item>
    <item name="android:layout_margin">0dp</item>
    <item name="actionTextColorAlpha">1.0</item>
</style>

<style name="MaterialSnackbarTextButtonTheme" parent="@style/Widget.MaterialComponents.Button.TextButton.Snackbar">
    <item name="backgroundTint">#7777ff</item>
    <item name="android:textColor">#ffffff</item>
</style>

<style name="MaterialSnackbarTextViewTheme" parent="@style/Widget.MaterialComponents.Snackbar.TextView">
    <item name="android:textColor">#ffffff</item>
    <item name="android:alpha">1.0</item>
</style>

Where drawable/snackbar_background.xml is:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle"
    >
    <solid android:color="#00cc77" />
</shape>

Don't forget to remove from Snackbar.make(), if you have added:

view.setBackgroundColor(ContextCompat.getColor(context, R.color.bg_color))
setActionTextColor(ContextCompat.getColor(context, R.color.button_color))

Unlike AlertDialog, Snackbar holds snackbarButtonStyle and snackbarTextViewStyle settings inside AppTheme (that's strange because yesterday they worked well inside MaterialSnackbarTheme).

As @StayCool said in comments, Snackbar currently uses transparency for background and text color (alpha = 0.5 - 0.6). Also they added round corners and margins. To remove background transparency, use either <item name="actionTextColorAlpha">1.0</item> or drawable/snackbar_background.xml. You can see his variant.

enter image description here

Share:
20,719
Konstantin Veretelnikov
Author by

Konstantin Veretelnikov

Updated on June 11, 2020

Comments

  • Konstantin Veretelnikov
    Konstantin Veretelnikov almost 4 years

    I need help. How can I change the design of the text in snackbar in styles app? The change in the code does not interest me. I found the following code. But it is not working for me. Why is that? My theme is derived from @style/Theme.AppCompat.Light.DarkActionBar". I would be very grateful for the help.

    <style name="TextAppearance.Design.Snackbar.Message" parent="android:TextAppearance">
            <item name="android:textSize">10sp</item>
            <item name="android:textColor">#FEFEFE</item>
        </style>
        <style name="TextAppearance.Design.Snackbar.Action" parent="android:TextAppearance">
            <item name="android:textSize">16sp</item>
            <item name="android:textColor">#FEFEFE</item>
        </style>
    
  • Jarett Millard
    Jarett Millard over 7 years
    This is the only way to style it in XML as of right now. There's a bug report in to allow styling it properly.
  • Andrew Hossam
    Andrew Hossam about 5 years
    If you are using the new material components use com.google.android.material.R.id.snackbar_text instead of android.support.design.R.id.snackbar_text
  • pablogeorge
    pablogeorge over 4 years
    Wonderful!!. Finally styling snackbar completly at theme level. Playing around with the above suggestion, I found that we can specify a custom background shape/color in the snack bar style. <style name="snackbar_style" parent="@style/Widget.MaterialComponents.Snackbar”> <item name="android:layout_margin">32dp</item> <item name="android:background">@drawable/bg_snackbar</item> <item name="backgroundTint”>@color/snackbarBackgroundColor</item> <item name="animationMode">slide</item> </style>
  • Jim Clermonts
    Jim Clermonts about 4 years
    when applying snackbar_button, the color is indeed changed. But the color is slightly more bright, and checking it with a color picker shows that the color is not exactly the chosen color.
  • StayCool
    StayCool almost 4 years
    How can I override primary/accent colors for snackbar only? I trie your solution but <item name="android:textColor">@color/white</item> just don't work for button textColor. Maybe ThemeOverlay?
  • CoolMind
    CoolMind almost 4 years
    @StayCool, I have just checked my example, these two colors don't affect SnackBar. I changed them and nothing has changed. Can you ask a question in SO?
  • CoolMind
    CoolMind almost 4 years
    @StayCool, that's strange. I changed button color in <item name="android:textColor"> and it applied.
  • CoolMind
    CoolMind almost 4 years
    @StayCool, did you set <item name="snackbarButtonStyle">@style/MaterialSnackbarTextButton‌​Theme</item> in the AppTheme?
  • StayCool
    StayCool almost 4 years
    yes, I did. my snackbar styles now contain a lot of attributes, because their parent styles contained selectors that used alpha 0.6 and some other things that was not obvious. i.e. when I set snackbar's button textColor to solid red, i ended up with 0.6 red. It was so confusing. Now I have succesfully changed background of snackbar with that: android:background, I set it to drawable gradient =) Also, I user material theme overlay to override colorPrimary user for button Stroke color.
  • CoolMind
    CoolMind almost 4 years
    @StayCool, yes, MDC Snackbar's background is partially transparent, so I set drawable/snackbar_background.xml. Good that you figured out all those bugs and features of MDC. :)
  • StayCool
    StayCool almost 4 years
    hmmm... if that was planned by material design maybe we don't wanna change that transparency? ^^ I was just confused because button's text was opaque, and snackbar's text wasn't
  • CoolMind
    CoolMind almost 4 years
    @StayCool, you are right! Transparency is often not needed, at least, if we didn't want. They changed this behaviour. I will test your solution. Thanks!
  • Gabriele Mariotti
    Gabriele Mariotti almost 4 years
    @StayCool About the background color it is not correct. The background color is based on the colorOnSurface You can override the color using <item name="materialThemeOverlay">@style/...</item> in your style (you can check my answer above). Using the backgroundTint the alpha layer is ignored. In any case you can override it using the attr backgroundOverlayColorAlpha. Finally you should avoid to use android:background.
  • StayCool
    StayCool almost 4 years
    @GabrieleMariotti but I can't use gradient background for snackbar with backgroundOverlayColorAlpha or overriding colorOnSurface for my snackBarStyle?
  • Gabriele Mariotti
    Gabriele Mariotti almost 4 years
    @StayCool With backgroundOverlayColorAlpha and backgroundTint you can't use gradient (as all the other components in material components library).
  • StayCool
    StayCool almost 4 years
    @GabrieleMariotti yes, and as I see, there is no other way to set drawable gradient for a snackbar, except android:background
  • Gabriele Mariotti
    Gabriele Mariotti almost 4 years
    @StayCool currently it is the only way.
  • Charly Lafon
    Charly Lafon over 3 years
    Thanks for super detailed post dude. Life saver