web-dev-qa-db-fra.com

Changer la couleur d'un commutateur

J'utilise un contrôle Switch standard avec le thème holo.light dans une application ICS.

Je souhaite changer la couleur d'état en surbrillance ou activée du bouton bascule du bleu clair au vert.

Cela devrait être facile, mais je n'arrive pas à comprendre comment le faire.

123
JamesSugrue

À partir de maintenant, il est préférable d’utiliser SwitchCompat à partir de la bibliothèque AppCompat.v7. Vous pouvez ensuite utiliser un style simple pour changer la couleur de vos composants.

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 des développeurs Android

EDIT:

La manière dont il devrait être correctement appliqué passe par Android:theme="@style/Theme.MyTheme" et peut également être appliqué aux styles parents tels que EditTexts, RadioButtons, Switches, CheckBoxes et ProgressBars:

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

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

Tard pour faire la fête mais c'est comme ça

Style

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

Couleurs

enter image description here

Mise en page

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

Résultat

Voir le changement de couleur pour les commutateurs enable et disabled

enter image description here

228
Hitesh Sahu

Cela fonctionne pour moi (nécessite 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);

Notez que l'état "par défaut" doit être ajouté en dernier, comme indiqué ici.

Le seul problème que je vois est que le "pouce" du commutateur semble maintenant plus grand que l'arrière-plan ou la "piste" du commutateur. Je pense que c'est parce que j'utilise toujours l'image de piste par défaut, qui est entourée d'un espace vide. Cependant, lorsque j'ai tenté de personnaliser l'image de la piste à l'aide de cette technique, il semblait que mon commutateur avait une hauteur de 1 pixel avec seulement une partie du texte activé/désactivé. Il doit y avoir une solution pour ça, mais je ne l’ai pas encore trouvée ...

Mise à jour pour Android 5

Dans Android 5, le code ci-dessus fait disparaître complètement le commutateur. Nous devrions pouvoir utiliser la nouvelle méthode setButtonTintList , mais cela semble être ignoré pour les commutateurs. Mais cela fonctionne:

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

Mise à jour pour Android 6-7

Comme Cheruby l'a déclaré dans les commentaires, nous pouvons utiliser le nouveau setThumbTintList et cela a fonctionné comme prévu pour moi. Nous pouvons également utiliser setTrackTintList, mais cela applique la couleur en tant que mélange, avec un résultat plus sombre que prévu dans les thèmes de couleurs sombres et plus clair que prévu dans les thèmes de couleurs claires, parfois même au point d'être invisible. Dans Android 7, j'ai été en mesure de minimiser ce changement en surchargeant la piste mode teinté , mais je ne pouvais pas obtenir de résultats décents dans Android. 6. Vous devrez peut-être définir des couleurs supplémentaires pour compenser le mélange. (Avez-vous parfois le sentiment que Google ne veut pas que nous personnalisions l'apparence de nos applications?)

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);
}
48
arlomedia

Créez un commutateur personnalisé et remplacez setChecked pour changer de couleur:

  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();
            }
        }
    }
}
31
francisco_ssb

Pour changer de style de commutateur sans utiliser le code style.xml ou Java, vous pouvez personnaliser le commutateur en XML de présentation:

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

C'est l'attribut Android: thumbTint et Android: trackTint qui vous a permis de personnaliser Couleur

Voici le résultat visuel de ce XML:

enter image description here

31
Kevin ABRIOUX

Bien que la réponse de SubChord soit correcte, elle ne répond pas vraiment à la question de savoir comment définir la couleur d'activation sans affecter également les autres widgets. Pour ce faire, utilisez un ThemeOverlay dans styles.xml:

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

Et référencez-le dans votre commutateur:

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

Cela affectera UNIQUEMENT la couleur des vues auxquelles vous souhaitez l'appliquer.

20
Greg Ennis

Je l'ai résolu en mettant à jour le filtre de couleur lorsque l'état du commutateur a été modifié ...

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);
    }
}
17
MCR

C'est peut-être un peu tard, mais pour les boutons de commutateur, le bouton bascule n'est pas la solution, vous devez modifier le dessin dans le paramètre xml du commutateur:

 Android:thumb="your drawable here"
12
Golgorz

Créez votre propre image de 9 correctifs et définissez-la comme arrière-plan du bouton à bascule.

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

7
you786

Dans Android Lollipop et au-dessus, définissez-le dans votre style de thème:

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

La solution suggérée par arlomedia a fonctionné pour moi. À propos de son problème d'extraspace, j'ai résolu de supprimer tous les rembourrages du commutateur.

MODIFIER

Comme demandé, voici ce que j'ai.

Dans le fichier de présentation, mon commutateur se trouve dans une présentation linéaire et après 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>

Depuis que je travaille avec Xamarin/Monodroid (min. Android 4.1), mon code est le suivant:

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 est précédemment défini comme ceci (Xamarin):

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

Je ne règle pas tous les bourrages et je n’appelle pas .setPadding (0, 0, 0, 0).

5
Daniele D.
<androidx.appcompat.widget.SwitchCompat
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                app:thumbTint="@color/white"
                app:trackTint="@drawable/checker_track"/>

Et à l'intérieur de 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>
5
wingear

vous pouvez créer un style personnalisé pour le widget de commutateur qui utilise l'accent de couleur par défaut lorsque le style personnalisé est activé

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

Vous pouvez essayer cette lib, facile à changer de couleur pour le bouton de commutation.
https://github.com/kyleduo/SwitchButtonenter image description here

2
Yang

Je ne sais pas comment le faire à partir de Java, mais si vous avez un style défini pour votre application, vous pouvez ajouter cette ligne à votre style et vous aurez la couleur souhaitée pour moi. J'ai déjà utilisé # 3F51B5.

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

Essayez de trouver la bonne réponse ici: Sélecteur sur la couleur de fond de TextView . En deux mots, vous devez créer une forme en XML avec une couleur, puis l’affecter à l’état "vérifié" dans votre sélecteur.

1
Shamm