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.
À 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">
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
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
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);
}
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();
}
}
}
}
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:
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.
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);
}
}
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"
Créez votre propre image de 9 correctifs et définissez-la comme arrière-plan du bouton à bascule.
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>
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).
<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>
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>
Vous pouvez essayer cette lib, facile à changer de couleur pour le bouton de commutation.
https://github.com/kyleduo/SwitchButton
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>
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.