如何更改Snackbar的背景颜色?

123

我正在DialogFragment中,在警报对话框的正面接触中显示snackbar。这是我的代码片段:

Snackbar snackbar = Snackbar.make(view, "Please enter customer name", Snackbar.LENGTH_LONG)
                .setAction("Action", null);
View sbView = snackbar.getView();
sbView.setBackgroundColor(Color.BLACK);
snackbar.show();

正如您所见,我的snackbar的背景颜色显示为白色

我正在将DialogFragment的视图传递给 snackbar。我想要将背景色设置为黑色。我该怎么做?我在DialogFragment中返回了alertDialog。并且我设置的对话框主题如下:

<style name="MyAlertDialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert">

    <!-- Used for the buttons -->
    <item name="colorAccent">@color/accent</item>
    <!-- Used for the title and text -->
    <item name="android:textColorPrimary">@color/primary</item>
    <!-- Used for the background -->
    <item name="android:background">@color/white</item>
</style>

虽然我将对话框的背景色设置为白色,但通过将背景色设置为 snackbar ,它应该被覆盖。


3
http://www.technotalkative.com/part-3-styling-snackbar/ - M D
我已经尝试过了,没有帮助...我正在从对话框片段+其中的AlertDialog调用snackbar,并将正按钮单击视图传递给snackbar。 - Ajinkya
21个回答

195

尝试像这样设置背景颜色:

sbView.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.BLACK));

百分之百可行!


58
您可能需要执行 snackBarView.getView().setBackgrondColor(ContextCompat.getColor(getActivity(), R.color.BLACK));。这将设置 Snackbar 视图的背景颜色为黑色,使用应用程序上下文和 R.color.BLACK。 - Jason John
3
如果您是从Google找到了这个页面,并且上面的解决方案没有起作用,您可能需要尝试使用以下代码:sbView.setBackgroundColor(getResources().getColor(R.color.BLACK))。请注意,此代码为Android编程中的一行代码。 - Gökhan Mete ERTÜRK
@modu 注意,自API级别23(Marshmallow)起,getResources#getColor已被弃用,应改用ContextCompat#getColor - Edric

94

你可以这样做

Snackbar snackbar;
snackbar = Snackbar.make(view, "Message", Snackbar.LENGTH_SHORT);
View snackBarView = snackbar.getView();
snackBarView.setBackgroundColor(yourColor);
TextView textView = (TextView) snackBarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setTextColor(textColor);
snackbar.show();

1
如您所见,我确实做了完全相同的事情,但它没有以黑色显示。 - Ajinkya
我在我的一个项目中使用了同样的内容,试图在活动中进行测试展示,可能由于对话框的原因它无法工作。 - Zubair Akber
是的,它在活动上运行良好,但我希望它在对话框片段上运行。 - Ajinkya
我认为这是因为您传递给它的视图。 - Zubair Akber

38

由于其他回答都没有提供自定义样式覆盖的方法(我认为这是最安全的更新方式之一),因此我在此发布我的解决方案。

我发布了一个解决方案,已经解决了新的 AndroidXsupport design 28)主题。

假设您的应用程序在AndroidManifest.xml中使用名为MyAppTheme的自定义主题:

<application
        android:name=".MyApplicationName"
        android:allowBackup="true"
        android:icon="@mipmap/icon"
        android:roundIcon="@mipmap/icon_round"
        android:label="@string/app_name"
        android:theme="@style/MyAppTheme">

如果您还没有创建,那么请创建values/style.xml文件,覆盖您的应用程序使用的主题:

<style name="MyAppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
    <item name="colorPrimary">@color/myColorPrimary</item>
    <item name="colorPrimaryDark">@color/myColorPrimaryDark</item>
    <item name="colorAccent">@color/myColorAccent</item>
    <item name="snackbarStyle">@style/MySnackBarStyle</item>
</style>

<!-- snackbar style in res/values -->
<style name="MySnackBarStyle" parent="Widget.MaterialComponents.Snackbar">
    <item name="android:background">@color/mySnackbarBackgroundColor</item>
</style>

并在您的values/colors.xml文件中提供您的颜色。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="myColorPrimary">#008577</color>
    <color name="myColorPrimaryDark">#00574B</color>
    <color name="myColorAccent">#D81B60</color>
    <color name="mySnackbarBackgroundColor">#D81B60</color>
</resources>

2020年更新

由于上述解决方案移除了snackbar的圆角,因为以这种方式设置背景使用了传统的snackbar设计,如果您想保留Material Design,则可以:

  1. 如果您的目标是API 21+

android:background替换为android:backgroundTint

<!-- snackbar style in res/values-21/ -->
<style name="MySnackBarStyle" parent="Widget.MaterialComponents.Snackbar">
    <item name="android:backgroundTint">@color/mySnackbarBackgroundColor</item>
</style>
  1. 如果您的目标API<21,则如果您决定在API<21中使用旧版snackbar,您可以将上述MySnackbarStyle设置在res/values-21/文件夹中,并保留以前的遗留样式在您的res/values文件夹中。

  2. 如果您的目标API<21并且希望在这些较低的API级别中也具有snackbar的材料样式,则可以通过以下方式更改在res/values/中的snackbar样式:

<!-- snackbar style in res/values/ -->
<style name="MySnackBarStyle" parent="Widget.MaterialComponents.Snackbar">
    <item name="android:background">@drawable/my_snackbar_background</item>
</style>

官方仓库 中借用你的 my_snackbar_background,方式如下:

<!-- in res/drawable/ -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="4dp"/>
    <solid android:color="@color/mySnackbarBackgroundColor"/>
</shape>

编辑于2022年:

如果您只想更改单个snackbar而不是整个应用程序,那么可以按照以下方式使用ContextThemeWrapper;

ContextThemeWrapper ctw = new ContextThemeWrapper(this, R.style.CustomSnackbarTheme);
customSnackBar = Snackbar.make(ctw, view, "", Snackbar.LENGTH_LONG);

并且在您的样式文件中

<style name="CustomSnackbarTheme">
    <item name="snackbarStyle">@style/MySnackBarStyle</item>
</style>

<style name="MySnackBarStyle" parent="Widget.MaterialComponents.Snackbar">
    <item name="android:background">@android:color/red</item>
</style>

这里有一个游乐场仓库

在这里输入图片描述


5
这是最干净和最好的解决方案。 - TrackDave
它改变了snackbar的大小。 - William
感谢my_snackbar_background。没有它,Snackbar的角会更圆润。 - CoolMind
我在 https://dev59.com/FlwY5IYBdhLWcg3wnY13#62006413 中添加了更多的样式。 - CoolMind
1
这是最佳解决方案。 - Abu Nayem
显示剩余2条评论

25

Kotlin版本(带有扩展extension):

在文件中创建一个扩展(例如SnackbarExtension.kt):

fun Snackbar.withColor(@ColorInt colorInt: Int): Snackbar{
   this.view.setBackgroundColor(colorInt)
   return this
}

接下来,在您的Activity/Fragment中,您将能够执行以下操作:

Snackbar
  .make(coordinatorLayout, message, Snackbar.LENGTH_LONG)
  .withColor(YOUR_COLOR)
  .show()

非常喜欢这个答案,我还添加了文本着色:fun Snackbar.withColor(@ColorInt backgroundColor: Int, @ColorInt textColor: Int) : Snackbar { this.view.setBackgroundColor(backgroundColor) this.view.findViewById(android.support.design.R.id.snackbar_text).setTextColor(textColor) return this } - willcwf

21

如果您想为所有的 Snackbar 定义一个背景颜色,只需在资源中覆盖 design_snackbar_background_color 值即可。例如:

如果您想为所有的 Snackbar 定义一个背景颜色,只需在资源中覆盖 design_snackbar_background_color 值即可。例如:

<color name="design_snackbar_background_color" tools:override="true">@color/colorPrimaryLight</color>

这个解决方案非常干净、漂亮。谢谢! - AloDev
1
非常好用,只需将其放入colors.xml中即可! - A P
不行,对我没用。其他的解决方案也都不行。 - Johann

18

使用Material Components Library,只需要使用setBackgroundTint方法即可。

    Snackbar snackbar = Snackbar.make(view, "Snackbar custom style", Snackbar.LENGTH_LONG);
    snackbar.setBackgroundTint(ContextCompat.getColor(this,R.color.secondaryColor));
    snackbar.show();

在此输入图片描述


使用 Jetpack Compose,您可以自定义 SnackbarHost 并定义自己的Snackbar

    snackbarHost = {
        // reuse default SnackbarHost to have default animation and timing handling
        SnackbarHost(it) { data ->
            Snackbar(
                snackbarData = data,
                backgroundColor = Color.Red
            )
        }
    },

那就直接使用它:

scope.launch {scaffoldState.snackbarHostState.showSnackbar("Snackbar text")}

输入图像描述


17

以下代码可用于更改消息的文本颜色。

Snackbar snackbar = Snackbar.make(rootView, "Enter Your Message",Snackbar.LENGTH_SHORT);
View view = snackbar.getView();
TextView tv = (TextView)view.findViewById(android.support.design.R.id.snackbar_text);
tv.setTextColor(Color.RED);
snackbar.show();

第二种方法:您也可以通过更改活动的主题来更改颜色。


7

如果还有人需要帮助,虽然现在已经有点晚了,但这是可行的解决方案。

      Snackbar snackbar = Snackbar.make(mainView, text, Snackbar.LENGTH_LONG);
    View snackBarView = snackbar.getView();
    snackBarView.setBackgroundColor(context.getResources().getColor(R.color.btn_background_color));
    snackbar.show();

4

在使用Xamarin Android过程中,我发现ContextCompat.GetColor()返回Int类型,而setBackgroundColor()需要一个Color类型的参数。

下面是我在我的xamarin android项目中使其正常工作的方法。

Snackbar snackbarview =  Snackbar.Make(toolbar, message, Snackbar.LengthLong);
View snckView = snackbarview.View;                
snckView.SetBackgroundColor(Color.ParseColor(GetString(Resource.Color.colorPrimary)));
snackbarview.Show();

使用Xamarin时,应该使用snackbarview.View来获取Snackbar的视图,而不是snackbar.getView(),因为前者在Xamarin中可用。但要注意,ParseColor可能会出现问题。 - Cfun
@Cfun能否更详细地解释一下你的问题,这样我才能帮助你。 - SATYAJEET RANJAN
我的错,我使用了 System.Drawing.Color.ParseColor 而不是 Android.Graphics.Color.ParseColor。现在我有一个错误信息:"当前上下文中不存在 'getstring' 的名称"。 - Cfun
@Cfun,你是在一个Activity或Fragment中遇到这个错误,还是在其他类中调用了getString()方法? - SATYAJEET RANJAN
@Cfun 确保你也传递了碎片的上下文或活动上下文,或者你可以尝试将应用程序上下文传递到你的其他类中,然后执行context.getString()它应该可以工作! - SATYAJEET RANJAN
显示剩余2条评论

4

我制作了一个小的工具类,以便在整个应用程序中轻松制作自定义颜色的 Snackbar。

package com.yourapppackage.yourapp;

import android.support.design.widget.Snackbar;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class SnackbarUtils {

    private int BACKGROUND_COLOR;
    private int TEXT_COLOR;
    private int BUTTON_COLOR;
    private String TEXT;


    public SnackbarUtils(String aText, int aBgColor, int aTextColor, int aButtonColor){
        this.TEXT = aText;
        this.BACKGROUND_COLOR = aBgColor;
        this.TEXT_COLOR = aTextColor;
        this.BUTTON_COLOR = aButtonColor;
    }

    public Snackbar snackieBar(){
        Snackbar snackie = Snackbar.make(MainActivity.getInstance().findViewById(android.R.id.content), TEXT, Snackbar.LENGTH_LONG);
        View snackView = snackie.getView();
        TextView snackViewText = (TextView) snackView.findViewById(android.support.design.R.id.snackbar_text);
        Button snackViewButton = (Button) snackView.findViewById(android.support.design.R.id.snackbar_action);
        snackView.setBackgroundColor(BACKGROUND_COLOR);
        snackViewText.setTextColor(TEXT_COLOR);
        snackViewButton.setTextColor(BUTTON_COLOR);
        return snackie;
    }
}

那么要在应用程序中使用它,就像这样:
new SnackbarUtils("This is the text displayed", Color.RED, Color.BLACK, Color.YELLOW).snackieBar().setAction("OTAY", v -> { 
     //donothing
     }).show();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接