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 setThumbTintList
e 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);
}
Switch
a questo selettore personalizzato in seguito.