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 apparaît maintenant plus grand que l'arrière-plan ou "piste" du commutateur. Je pense que c'est parce que j'utilise toujours l'image de piste par défaut, qui a un espace vide autour d'elle. Cependant, lorsque j'ai essayé de personnaliser l'image de la piste à l'aide de cette technique, mon commutateur semblait avoir une hauteur de 1 pixel avec juste un ruban du texte d'activation / désactivation apparaissant. Il doit y avoir une solution pour ça, mais je ne l'ai pas encore trouvée ...
Mise à jour pour Android 5
Sous 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 l'a déclaré Cheruby 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 comme un 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 au point d'être invisible. Dans Android 7, j'ai pu minimiser ce changement en remplaçant le mode de teinte de la piste , mais je ne pouvais pas obtenir de résultats décents avec Android 6. Vous devrez peut-être définir des couleurs supplémentaires qui compensent le mélange. (Avez-vous déjà eu 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);
}
Switch
vers ce sélecteur personnalisé par la suite.