Come cambiare il colore di sfondo dello snackbar?


101

Sto mostrando snackbar in DialogFragment all'interno del clic positivo di alertDialog. Ecco il mio frammento di codice.

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();

Come puoi vedere il colore di sfondo del mio snackbar mostra il colore bianco

Passo la vista del frammento di dialogo allo snackbar. Voglio il colore di sfondo nero? Come posso fare questo? Sto restituendo alertDialog nel DialogFragment. E il tema che sto impostando per la finestra di dialogo è il seguente

<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>

Sebbene imposti il ​​colore di sfondo su bianco per la finestra di dialogo, dovrebbe sovrascrivere impostando il colore di sfondo sulla barra degli spuntini.



provato che già non mi aiuta ... sto chiamando lo snack bar dal frammento di dialogo + alertDialog in esso e sto passando la visualizzazione del clic del pulsante positivo alla snackbar
Ajinkya

Risposte:


171

Prova a impostare il colore di sfondo in questo modo:

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

Funzionerà al 100%!


50
potresti dover faresnackBarView.getView().setBackgrondColor(ContextCompat.getColor(getActivity(), R.color.BLACK));
jaytj95

2
Se hai trovato questa pagina di Google e la soluzione sopra non ha funzionato per te, potresti dover provare questa invece:sbView.setBackgroundColor(getResources().getColor(R.color.BLACK))
modu

@modu Nota che getResources#getColorè stato deprecato dal livello API 23 (Marshmallow) e ContextCompat#getColordovrebbe essere utilizzato al suo posto.
Edric

89

puoi farlo in questo modo

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
come puoi vedere ho fatto esattamente la stessa cosa ma non si vedeva in colore nero
Ajinkya

Ho usato lo stesso in uno dei miei progetti, provo a visualizzarlo in attività per i test, potrebbe non funzionare a causa del dialogo
Zubair Akber

stai lavorando sull'attività ma lo voglio sul frammento di dialogo.
Ajinkya

penso che sia a causa della tua opinione che ci stai passando
Zubair Akber

20

Se desideri definire un colore di sfondo per tutti i tuoi snack bar, sovrascrivi il design_snackbar_background_colorvalore da qualche parte nelle tue risorse. Per esempio:

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

Questa soluzione è più pulita e piacevole. Grazie!
AloDev

1
Funziona alla grande, basta inserirlo in colors.xml e il gioco è fatto!
Avi Parshan

No. Non ha funzionato per me. Nemmeno le altre soluzioni.
AndroidDev

20

Poiché nessuna delle altre risposte ha fornito una sostituzione dello stile personalizzato (che considero uno dei modi di aggiornamento più sicuri per farlo), posto qui la mia soluzione.

Inserisco una soluzione che già affronta il tema new AndroidX( support design 28).

A condizione che la tua applicazione utilizzi un nome personalizzato chiamato MyAppThemenel tuo AndroidManifest.xml:

<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">

Crea (se non lo hai già fatto) values/style.xmlfile sovrascrivendo il tema utilizzato dalla tua applicazione:

<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>

e fornisci i tuoi colori nel tuo values/colors.xmlfile

<?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>

AGGIORNAMENTO 2020

Poiché la soluzione di cui sopra rimuove l'angolo arrotondato dello snacker perché l'impostazione dello sfondo in questo modo utilizza il design legacy dello snackbar, se si desidera preservare il design del materiale è possibile.

  1. Se scegli come target API 21+

sostituire android:backgroundconandroid:backgroundTint

<!-- snackbar style in res/values-21/ -->
<style name="MySnackBarStyle" parent="Widget.MaterialComponents.Snackbar">
    <item name="android:backgroundTint">@color/mySnackbarBackgroundColor</item>
</style>
  1. Se scegli come target API <21, se decidi di utilizzare lo snackbar legacy per API <21 puoi impostare il tuo abouve MySnackbarStylenella cartella res / values-21 / e lasciare lo stile precedente - legacy - nella cartella res / values .

  2. Se stai prendendo di mira API <21 e vuoi avere lo stile materiale della snackbar anche in questi livelli API inferiori, puoi cambiare lo stile della tua snackbar nei tuoi res / valori / in questo modo:

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

e prendi in prestito il tuo my_snackbar_backgrounddal repository ufficiale , in questo modo:

<!-- 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>

Ecco un repository del parco giochi .

inserisci qui la descrizione dell'immagine


3
Questa è la soluzione più pulita e migliore
TrackDave

Cambia la dimensione dello snakbar
William il

Nota che il tuo AppTheme deve ereditare da Theme.MaterialComponents per essere compilato
A.Mamode

Grazie per my_snackbar_background. Senza di essa Snackbar disegnava con angoli più arrotondati.
CoolMind

Ho aggiunto un po 'più di stile in stackoverflow.com/a/62006413/2914140 .
CoolMind

15

Versione Kotlin (con un'estensione ):

Crea in un file (ad esempio SnackbarExtension.kt) un'estensione:

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

Successivamente, nella tua attività / frammento, sarai in grado di fare questo:

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

Mi piace molto questa risposta, ho aggiunto anche la colorazione del testo: fun Snackbar.withColor (@ColorInt backgroundColor: Int, @ColorInt textColor: Int): Snackbar {this.view.setBackgroundColor (backgroundColor) this.view.findViewById <TextView> ( android.support.design.R.id.snackbar_text) .setTextColor (textColor) return this}
willcwf

13

Il codice seguente è utile per modificare il colore del testo del messaggio.

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();

Secondo modo: puoi cambiare colore anche cambiando il tema dell'attività.


7

È troppo tardi, ma nel caso qualcuno avesse ancora bisogno di aiuto. Ecco la soluzione di lavoro.

      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

Mentre lavoravo con xamarin Android ho scoperto che ContextCompat.GetColor () restituisce Int ma setBackgroundColor () si aspetta un parametro di tipo Color. Quindi ecco come l'ho fatto funzionare nel mio progetto Android Xamarin.

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

+1 per Xamarin View snckView = snackbarview.View;invece snackbar.getView();che non è disponibile ma ParseColornon funziona.
Cfun

@ Fun Puoi spiegare un po 'di più il tuo problema, così posso aiutarti con esso.
SATYAJEET RANJAN

Il mio male l'ho usato al System.Drawing.Color.ParseColorposto di Android.Graphics.Color.ParseColor. ora ho: "il nome 'getstring' non esiste nel contesto corrente"
Cfun

@Cfun Stai ricevendo questo errore in un'attività o un frammento o stai chiamando getString () in qualche altra classe?
SATYAJEET RANJAN

Lo chiamo in qualche altra classe.
Cfun


2

Ho fatto un piccolo corso di utilità in modo da poter creare facilmente snack bar colorati personalizzati attraverso l'app.

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;
    }
}

quindi per usarlo, in questo modo ovunque nell'app:

new SnackbarUtils("This is the text displayed", Color.RED, Color.BLACK, Color.YELLOW).snackieBar().setAction("OTAY", v -> { 
     //donothing
     }).show();

2

Mettilo in una classe Utility:

public class Utility {
    public static void showSnackBar(Context context, View view, String text) {
        Snackbar sb = Snackbar.make(view, text, Snackbar.LENGTH_SHORT);
        sb.getView().setBackgroundColor(ContextCompat.getColor(context, R.color.colorAccent));
        sb.show();
    }
}

Usando in questo modo:

Utility.showSnackBar(getApplicationContext(), findViewById(android.R.id.content), "Add success!!!");

2

Fondamentalmente, le soluzioni fornite hanno uno svantaggio. Cambiano la forma dello snackbar e rimuovono il raggio.

Personalmente, preferisco qualcosa del genere

val snackbar = Snackbar.make(view, text, Snackbar.LENGTH_LONG);
val view = snackbar.getView();
val color = view.resources.getColor(colorId)
view.background.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)

1

Nessuna delle altre soluzioni ha funzionato davvero per me. Se ho impostato solo il colore di sfondo di Snackbar, il layout in TextView e Button era nel colore predefinito. Se ho impostato lo sfondo di TextView, ha lampeggiato un po 'dopo che SnackBar è stato mostrato. E il layout intorno al pulsante era ancora nel colore predefinito.

Alla fine ho scoperto che il modo migliore per me è cambiare il colore di sfondo del genitore di TextView (SnackbarContentLayout). Ora l'intero Snackbar è colorato correttamente e non lampeggia quando viene visualizzato.

snack = Snackbar.make(view, text, duration)
View view = snack.getView();
view.setBackgroundColor(BACKGROUND_COLOR);
TextView tv = view.findViewById(android.support.design.R.id.snackbar_text);
tv.setTextColor(TEXT_COLOR);
((SnackbarContentLayout) tv.getParent()).setBackgroundColor(BACKGROUND_COLOR);

1

setBackgroundResource() funziona altrettanto bene.

Snackbar snackbar = Snackbar.make(view, text, Snackbar.LENGTH_LONG);
View sbView = snackbar.getView();
sbView.setBackgroundResource(R.color.background);
snackbar.show();

1

Non so perché setBackgroundColor () non ha trovato nel mio progetto. Ecco perché ho creato una funzione di estensione e ora va bene.

fun View.showSnackBar(message: String) {
    val snackBar = Snackbar.make(this, message, Snackbar.LENGTH_LONG)
    snackBar.setBackgroundTint(ContextCompat.getColor(this.context, R.color.colorAccent))
    snackBar.show()
}

e chiamalo come muggito

activity_login.xml

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/login_holder_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

   // your UI

</FrameLayout>

LoginActivity.kt

login_holder_layout.showSnackBar("Invalid Email") 

0
public class CustomBar {

public static void show(View view, String message, boolean isLong) {
    Snackbar s = Snackbar.make(view, message, isLong ? Snackbar.LENGTH_LONG : Snackbar.LENGTH_SHORT);
    s.getView().setBackgroundColor(ContextCompat.getColor(view.getContext(), R.color.red_900));
    s.show();
}

public static void show(View view, @StringRes int message, boolean isLong) {
    Snackbar s = Snackbar.make(view, message, isLong ? Snackbar.LENGTH_LONG : Snackbar.LENGTH_SHORT);
    s.getView().setBackgroundColor(ContextCompat.getColor(view.getContext(), R.color.red_900));
    s.show();
}

}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.