Cambia il colore "on" di uno Switch


156

Sto usando un controllo Switch standard con il tema holo.light in un'app ICS.

Voglio cambiare il colore di stato evidenziato o acceso del pulsante Attiva / Disattiva da blu chiaro standard a verde.

Dovrebbe essere facile, ma non riesco a capire come farlo.


Non vedo altro che copiare le risorse della piattaforma pertinenti (selettore e file * .png) e modificare il disegnabile dello stato 'on'. Non dimenticare di puntare Switcha questo selettore personalizzato in seguito.
MH.

Risposte:


101

A partire da ora è meglio usare SwitchCompat dalla libreria AppCompat.v7. È quindi possibile utilizzare uno stile semplice per modificare il colore dei componenti.

values/themes.xml:

<style name="Theme.MyTheme" parent="Theme.AppCompat.Light">
    <!-- colorPrimary is used for the default action bar background -->
    <item name="colorPrimary">@color/my_awesome_color</item>

    <!-- colorPrimaryDark is used for the status bar -->
    <item name="colorPrimaryDark">@color/my_awesome_darker_color</item>

    <!-- colorAccent is used as the default value for colorControlActivated,
         which is used to tint widgets -->
    <item name="colorAccent">@color/accent</item>

    <!-- You can also set colorControlNormal, colorControlActivated
         colorControlHighlight, and colorSwitchThumbNormal. -->

</style>

ref: Blog degli sviluppatori Android

MODIFICA :

Il modo in cui dovrebbe essere applicato correttamente è attraverso android:theme="@style/Theme.MyTheme" e anche questo può essere applicato a stili principali come EditTexts, RadioButtons, Switches, CheckBoxes e ProgressBars:

<style name="My.Widget.ProgressBar" parent="Widget.AppCompat.ProgressBar">

<style name="My.Widget.Checkbox" parent="Widget.AppCompat.CompoundButton.CheckBox">

1
Anche se non applicabile al momento, questa dovrebbe essere la risposta accettata!
Andrew Gallasch,

Ho cambiato questo nella risposta accettata, in quanto sembra l'approccio più "moderno" a questa domanda.
JamesSugrue,

1
Ho provato tutti questi e nessuno di loro ha cambiato il colore dello stato "on" per il mio interruttore.
Adam Johns,

31
'on' è colorAccent, 'off' è colorSwitchThumbNormal. Se si utilizza il AppCompattema, è necessario utilizzare SwitchCompatanziché Switch. Se si utilizza SDK 23+, è possibile utilizzare android:thumbTinte android:thumbTintModecon a ColorStateList.
Tom,

1
@Tom plz risponderà che le cose 'android: thumbTint' funzioneranno su dispositivi <23
Shirish Herwade,

269

In ritardo alla festa, ma è così che ho fatto

Stile

 <style name="SCBSwitch" parent="Theme.AppCompat.Light">
        <!-- active thumb & track color (30% transparency) -->
        <item name="colorControlActivated">#46bdbf</item>

        <!-- inactive thumb color -->
        <item name="colorSwitchThumbNormal">#f1f1f1
        </item>

        <!-- inactive track color (30% transparency) -->
        <item name="android:colorForeground">#42221f1f
        </item>
    </style>

Colori

inserisci qui la descrizione dell'immagine

disposizione

<android.support.v7.widget.SwitchCompat
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:checked="false"
    android:theme="@style/SCBSwitch" />

Risultato

Vedi cambio di colore per abilitazione e disabilitazione interruttore

inserisci qui la descrizione dell'immagine


14
@MaksimKniazev Devi usare SwitchCompat;)
Ovi Trif

1
Buono, tranne colorControlActivated: non imposta il colore della traccia, ma solo il colore del pollice.
Puntatore Null

1
ecco la soluzione per Switch e SwitchCompat: stackoverflow.com/a/47036089/5869630
Hosseini roghayeh

I tag <style> dovevano essere scritti sotto res >> valori >> styles.xml e nella pagina XML per <Switch ...> dovresti aggiungere solo la linea chiamata: android: theme = "@ style / SCBSwitch ei miei colori sono : colorControlActivated "> # ff0000 e colorSwitchThumbNormal"> # 00ff00 e android: colorForeground "> # 00ff00
Baia

@OviTrif Fantastico! È impressionante quanto sia difficile trovare un'informazione semplice come quella. Molte e molte risposte che ho letto, e nessuno, ha dato una risposta funzionante fino ad ora. Finalmente!
jairhumberto

49

Questo funziona per me (richiede Android 4.1):

Switch switchInput = new Switch(this);
int colorOn = 0xFF323E46;
int colorOff = 0xFF666666;
int colorDisabled = 0xFF333333;
StateListDrawable thumbStates = new StateListDrawable();
thumbStates.addState(new int[]{android.R.attr.state_checked}, new ColorDrawable(colorOn));
thumbStates.addState(new int[]{-android.R.attr.state_enabled}, new ColorDrawable(colorDisabled));
thumbStates.addState(new int[]{}, new ColorDrawable(colorOff)); // this one has to come last
switchInput.setThumbDrawable(thumbStates);

Si noti che lo stato "predefinito" deve essere aggiunto per ultimo, come mostrato qui.

L'unico problema che vedo è che il "pollice" dell'interruttore ora appare più grande dello sfondo o della "traccia" dell'interruttore. Penso che sia perché sto ancora usando l'immagine di traccia predefinita, che ha uno spazio vuoto attorno ad essa. Tuttavia, quando ho tentato di personalizzare l'immagine della traccia usando questa tecnica, il mio interruttore sembrava avere un'altezza di 1 pixel con solo un frammento del testo on / off. Deve esserci una soluzione per questo, ma non l'ho ancora trovata ...

Aggiornamento per Android 5

In Android 5, il codice sopra fa scomparire completamente l'interruttore. Dovremmo essere in grado di utilizzare il nuovo metodo setButtonTintList , ma questo sembra essere ignorato per gli switch. Ma questo funziona:

ColorStateList buttonStates = new ColorStateList(
        new int[][]{
                new int[]{-android.R.attr.state_enabled},
                new int[]{android.R.attr.state_checked},
                new int[]{}
        },
        new int[]{
                Color.BLUE,
                Color.RED,
                Color.GREEN
        }
);
switchInput.getThumbDrawable().setTintList(buttonStates);
switchInput.getTrackDrawable().setTintList(buttonStates);

Aggiornamento per Android 6-7

Come Cheruby ha affermato nei commenti, possiamo usare il nuovo setThumbTintListe ha funzionato come previsto per me. Possiamo anche usare setTrackTintList, ma questo applica il colore come una fusione, con un risultato più scuro del previsto nei temi di colore scuro e più chiaro del previsto nei temi di colore chiaro, a volte al punto di essere invisibile. In Android 7, sono stato in grado di ridurre al minimo tale modifica sovrascrivendo la modalità Tinta traccia , ma non sono riuscito a ottenere risultati decenti da quello in Android 6. Potrebbe essere necessario definire colori extra che compensano la fusione. (Hai mai la sensazione che Google non voglia che personalizziamo l'aspetto delle nostre app?)

ColorStateList thumbStates = new ColorStateList(
        new int[][]{
                new int[]{-android.R.attr.state_enabled},
                new int[]{android.R.attr.state_checked},
                new int[]{}
        },
        new int[]{
                Color.BLUE,
                Color.RED,
                Color.GREEN
        }
);
switchInput.setThumbTintList(thumbStates);
if (Build.VERSION.SDK_INT >= 24) {
    ColorStateList trackStates = new ColorStateList(
            new int[][]{
                    new int[]{-android.R.attr.state_enabled},
                    new int[]{}
            },
            new int[]{
                    Color.GRAY,
                    Color.LTGRAY
            }
    );
    switchInput.setTrackTintList(trackStates);
    switchInput.setTrackTintMode(PorterDuff.Mode.OVERLAY);
}

Sto usando l'approccio getThumbDrawable / getTrackDrawable per creare un interruttore in cui entrambi gli stati hanno lo stesso colore - in altre parole, l'interruttore non abilita / disabilita qualcosa, ma viene usato per scegliere tra due alternative.
Natix,

4
Capito che DrawableCompat.setTintList gli permetterà di funzionare su dispositivi precedenti. Chiamo: DrawableCompat.setTintList (switchCompat.getThumbDrawable (), foregroundState);
Alexey,

Modifica la risposta per includere la soluzione DrawableCompat. Funziona perfettamente!
Dmytro Karataiev,

API 23+: switchInput.setThumbTintList(buttonStates); funziona anche per Nougat. API 21-22: utilizzare DrawableCompat come suggerito da @Alexey. Il switchInput.setButtonTintList(buttonStates);non ha funzionato per me, non ha colore gli stati per il mio interruttore. API sotto 21: hanno switchInput.getThumbDrawable().setColorFilter(someColor, PorterDuff.Mode.SrcIn); funzionato per me. Ho lavorato anche con Xamarin, quindi traduci quelli in C # nei render Android se usi Xamarin.Forms.
Cheruby,

37

Per modificare lo stile di Switch senza utilizzare style.xml o il codice Java, è possibile personalizzare lo switch nel layout XML:

<Switch
        android:id="@+id/checkbox"
        android:layout_width="wrap_content"
        android:thumbTint="@color/blue"
        android:trackTint="@color/white"
        android:checked="true"
        android:layout_height="wrap_content" />

È l'attributo android: thumbTint e android: trackTint che ti ha permesso di personalizzare il colore

Questo è il risultato visivo di questo XML:

inserisci qui la descrizione dell'immagine


17
Questo cambia il colore del pollice, indipendentemente dal fatto che sia acceso o spento.
sviluppatore Android

1
"Attributo thumbTint viene utilizzato solo nel livello API 21 e superiore"
norbDEV,

6
@norbDEV usa app: thumbTint e app: trackTint con SwitchCompat dalla libreria AppCompat.v7 per un livello API inferiore.
David Darias,

Funziona, ma cosa succede se si desidera cambiare il colore per il pollice, a seconda che sia acceso o spento?
TavernSenses

2
Se vuoi usare thumbTint sotto 21, usa app:thumbTintinvece di android:thumbTinte cambia switchconSwitchCompat
Kavita_p

33

Crea uno Switch personalizzato e sostituisci set Controllato per cambiare colore:

  public class SwitchPlus extends Switch {

    public SwitchPlus(Context context) {
        super(context);
    }

    public SwitchPlus(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SwitchPlus(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void setChecked(boolean checked) {
        super.setChecked(checked);
        changeColor(checked);
    }

    private void changeColor(boolean isChecked) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            int thumbColor;
            int trackColor;

            if(isChecked) {
                thumbColor = Color.argb(255, 253, 153, 0);
                trackColor = thumbColor;
            } else {
                thumbColor = Color.argb(255, 236, 236, 236);
                trackColor = Color.argb(255, 0, 0, 0);
            }

            try {
                getThumbDrawable().setColorFilter(thumbColor, PorterDuff.Mode.MULTIPLY);
                getTrackDrawable().setColorFilter(trackColor, PorterDuff.Mode.MULTIPLY);
            }
            catch (NullPointerException e) {
                e.printStackTrace();
            }
        }
    }
}

2
Il primo post che in realtà mi ha aiutato a ottenere colori personalizzati per l'interruttore materiale senza usare stile o temi. Grazie !
Mackovich,

1
Bello. Avevo già il mio Switch personalizzato, quindi ho dovuto solo sostituire il metodo setChecked e tutti hanno cambiato automaticamente i loro colori. Grazie dalla Spagna.
Julio,

22

Mentre la risposta di SubChord è corretta, in realtà non risponde alla domanda su come impostare il colore "on" senza influire anche su altri widget. Per fare ciò, usa a ThemeOverlayin styles.xml:

<style name="ToggleSwitchTheme" parent="ThemeOverlay.AppCompat.Light">
    <item name="colorAccent">@color/green_bright</item>
</style>

E fai riferimento nel tuo interruttore:

<android.support.v7.widget.SwitchCompat
  android:theme="@style/ToggleSwitchTheme" ... />

In tal modo influirà SOLO sul colore delle viste a cui si desidera applicarlo.


Per qualche motivo, ho anche dovuto impostare "colorControlActivated" sullo stesso valore, eppure su POC era sufficiente usare "colorAccent". Come mai?
sviluppatore Android

22
<androidx.appcompat.widget.SwitchCompat
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:thumbTint="@color/white"
                app:trackTint="@drawable/checker_track"/>

E dentro checker_track.xml:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/lightish_blue" android:state_checked="true"/>
    <item android:color="@color/hint" android:state_checked="false"/>
</selector>

thumbTintsi applica solo su Android API 21 e versioni successive. E se volessi cambiare colore sotto Android 21?
Giovanka Bisano,

developer.android.com/reference/android/support/v7/widget/… SwitchCompat è retrocompatibile con API 7 e successive
wingear

1
È il 2020. Mi chiedo davvero dove nel mondo le persone utilizzino ancora Android 21 e versioni precedenti?
zeeshan,

18

L'ho risolto aggiornando il filtro colore quando lo stato Switch era stato cambiato ...

public void bind(DetailItem item) {
    switchColor(item.toggle);
    listSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                switchColor(b);
        }
    });
}

private void switchColor(boolean checked) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        listSwitch.getThumbDrawable().setColorFilter(checked ? Color.BLACK : Color.WHITE, PorterDuff.Mode.MULTIPLY);
        listSwitch.getTrackDrawable().setColorFilter(!checked ? Color.BLACK : Color.WHITE, PorterDuff.Mode.MULTIPLY);
    }
}

13

Potrebbe essere un po 'tardi, ma per i pulsanti switch, il pulsante toogle non è la risposta, è necessario modificare il disegno nel parametro xml dello switch:

 android:thumb="your drawable here"

9

rendere disegnabile "newthumb.xml"

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/Green" android:state_checked="true"/>
    <item android:color="@color/Red" android:state_checked="false"/>
</selector>

e crea "newtrack.xml" disegnabile

<selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:color="@color/black" android:state_checked="true"/>
        <item android:color="@color/white" android:state_checked="false"/>
    </selector>

e aggiungilo in Switch:

<Switch
        android:trackTint="@drawable/newtrack"
        android:thumbTint="@drawable/newthumb"
         />

1
Questo funziona Tuttavia, va notato che AndroidStudio non sarà in grado di suggerire risorse @drawable per trackTinto thumbTint. Bisogna scriverlo manualmente e funziona.
Benjamin Basmaci,

Per qualche motivo questa è l'unica risposta che funziona in modo affidabile sul mio Huawei. Grazie!
einUsername

7

In Android Lollipop e versioni successive, definiscilo nel tuo stile del tema:

<style name="BaseAppTheme" parent="Material.Theme">
    ...
    <item name="android:colorControlActivated">@color/color_switch</item>
</style>

Il problema con questa soluzione è che cambia anche i colori dei miei textedits selezionati che non è quello che voglio.
codewing

@codewing Certo che lo sarà. Perché questo è impostato nella preferenza di stile globale. Al fine di raggiungere il tuo obiettivo, è quello di trovare l'id della vista target e modificarne gli attributi.
emen

OK, questo è per la posizione "On". Che ne dici di cambiare il colore del pollice per la posizione "Off"?
TavernSenses

7

Crea la tua immagine da 9 patch e impostala come sfondo del pulsante di attivazione / disattivazione.

http://radleymarx.com/2011/simple-guide-to-9-patch/


2
Sì, potrebbe farlo, ma sicuramente DEVE esserci un modo più semplice? Selettori forse?
JamesSugrue,

No, non esiste un modo più semplice. Non puoi cambiare magicamente il colore di un'immagine :)
you786,

Buon punto. Non ho capito bene come funzionava fino a quando non ho avuto uno sguardo più profondo.
JamesSugrue,

@ Denizen, sei sicuro? In tal caso, pubblica una risposta e la voterò.
tu786

@ Denizen Rimuovi il tuo commento. Android Switch restituisce sempre null per getBackground (), ho perso 30 minuti provando questo.
Shirish Herwade,

5

La soluzione suggerita da Arlomedia ha funzionato per me. A proposito del suo problema con extraspace ho risolto la rimozione di tutte le imbottiture sullo switch.

MODIFICARE

Come richiesto, ecco quello che ho.

Nel file di layout, il mio switch si trova all'interno di un layout lineare e dopo un TextView.

<LinearLayout
        android:id="@+id/myLinearLayout"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_gravity="center_horizontal|center"
        android:gravity="right"
        android:padding="10dp"
        android:layout_marginTop="0dp"
        android:background="@drawable/bkg_myLinearLayout"
        android:layout_marginBottom="0dp">
        <TextView
            android:id="@+id/myTextForTheSwitch"
            android:layout_height="wrap_content"
            android:text="@string/TextForTheSwitch"
            android:textSize="18sp"
            android:layout_centerHorizontal="true"
            android:layout_gravity="center_horizontal|center"
            android:gravity="right"
            android:layout_width="wrap_content"
            android:paddingRight="20dp"
            android:textColor="@color/text_white" />
        <Switch
            android:id="@+id/mySwitch"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textOn="@string/On"
            android:textOff="@string/Off"
            android:layout_centerHorizontal="true"
            android:layout_gravity="center_horizontal"
            android:layout_toRightOf="@id/myTextForTheSwitch"
            android:layout_alignBaseline="@id/myTextForTheSwitch"
            android:gravity="right" />
    </LinearLayout>

Dal momento che sto lavorando con Xamarin / Monodroid (min. Android 4.1) il mio codice è:

Android.Graphics.Color colorOn = Android.Graphics.Color.Green;
Android.Graphics.Color colorOff = Android.Graphics.Color.Gray;
Android.Graphics.Color colorDisabled = Android.Graphics.Color.Green;

StateListDrawable drawable = new StateListDrawable();
drawable.AddState(new int[] { Android.Resource.Attribute.StateChecked }, new ColorDrawable(colorOn));
drawable.AddState(new int[] { -Android.Resource.Attribute.StateEnabled }, new ColorDrawable(colorDisabled));
drawable.AddState(new int[] { }, new ColorDrawable(colorOff));

swtch_EnableEdit.ThumbDrawable = drawable;

swtch_EnableEdit è stato precedentemente definito come questo (Xamarin):

Switch swtch_EnableEdit = view.FindViewById<Switch>(Resource.Id.mySwitch);

Non imposto affatto i padding e non chiamo .setPadding (0, 0, 0, 0).


Puoi fornire il codice per questo? Ho provato switchInput.setPadding (0, 0, 0, 0) ma non è cambiato nulla.
arlomedia,

1
Testato in Xamarin utilizzando la libreria AppCompat per il target 5.x e ha funzionato come pubblicizzato.
Alex.Ritna,

4

puoi creare uno stile personalizzato per il widget switch che utilizza l'accento di colore come predefinito quando esegui uno stile personalizzato

<style name="switchStyle" parent="Theme.AppCompat.Light">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorPrimary</item>    <!-- set your color -->
</style>    



1

Non so come farlo da Java, ma se hai uno stile definito per la tua app puoi aggiungere questa linea nel tuo stile e avrai il colore desiderato per me che ho usato # 3F51B5

<color name="ascentColor">#3F51B5</color>

1

Il modo più semplice è definire la tinta della traccia e impostare la modalità tinta su src_over per rimuovere il 30% di trasparenza.

android:trackTint="@drawable/toggle_style"
android:trackTintMode="src_over"

toggle_style.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/informationDefault"
        android:state_checked="true"
        />
    <item android:color="@color/textDisabled" android:state_checked="false"/>
</selector>

0

In aggiunta alle risposte esistenti: puoi personalizzare il pollice e la traccia utilizzando i selettori nella res/colorcartella, ad esempio:

switch_track_selector

<?xml version="1.0" encoding="utf-8"?>
<selector
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/lightBlue"
        android:state_checked="true" />
    <item android:color="@color/grey"/>
</selector>

switch_thumb_selector

<selector
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/darkBlue"
        android:state_checked="true" />
    <item android:color="@color/white"/>
</selector>

Utilizzare questi selettori per personalizzare le tinte di traccia e pollice:

<androidx.appcompat.widget.SwitchCompat
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:trackTint="@color/switch_track_selector"
    app:thumbTint="@color/switch_thumb_selector"/>

Tieni presente che se usi standart Switche androidnamespace per questi attributi, funzionerà solo per API 23 e successive, quindi usa SwitchCompatcon appnamespacexmlns:app="http://schemas.android.com/apk/res-auto" come soluzione universale.

Risultato:

inserisci qui la descrizione dell'immagine


0

In XML, puoi cambiare il colore come:

 <androidx.appcompat.widget.SwitchCompat
    android:id="@+id/notificationSwitch"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:checked="true"
    app:thumbTint="@color/darkBlue"
    app:trackTint="@color/colorGrey"/>

Dinamicamente puoi cambiare come:

Switch.thumbDrawable.setColorFilter(ContextCompat.getColor(requireActivity(), R.color.darkBlue), PorterDuff.Mode.MULTIPLY)

-1

Soluzione per Android Studio 3.6:

yourSwitch.setTextColor(getResources().getColor(R.color.yourColor));

Modifica il colore del testo di un valore definito nel file XML a colori (yourColor).

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.