Это работает для меня (требуется 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);
Обратите внимание, что состояние «по умолчанию» должно быть добавлено последним, как показано здесь.
Единственная проблема, которую я вижу, состоит в том, что «большой палец» переключателя теперь кажется больше, чем фон или «дорожка» переключателя. Я думаю, это потому, что я все еще использую изображение дорожки по умолчанию, вокруг которого есть свободное место. Однако, когда я попытался настроить изображение дорожки, используя эту технику, мой переключатель, как оказалось, имел высоту 1 пиксель с появлением лишь небольшого количества включенного / выключенного текста. Должно быть решение для этого, но я еще не нашел его ...
Обновление для Android 5
В Android 5 приведенный выше код заставляет переключатель полностью исчезнуть. Мы должны иметь возможность использовать новый метод setButtonTintList , но, похоже, это игнорируется для переключателей. Но это работает:
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);
Обновление для Android 6-7
Как сказал Херувим в комментариях, мы можем использовать новое, setThumbTintList
и это сработало, как я ожидал. Мы также можем использовать setTrackTintList
, но это применяет цвет как смесь, в результате чего в темных цветовых темах оно темнее, чем ожидалось, а в светлых темах светлее, чем ожидалось, иногда до такой степени, что оно становится невидимым. В Android 7 мне удалось минимизировать это изменение, переопределив режим оттенка дорожки , но я не смог получить приличные результаты из этого в Android 6. Возможно, вам потребуется определить дополнительные цвета, которые компенсируют смешивание. (У вас когда-нибудь возникало ощущение, что Google не хочет, чтобы мы настраивали внешний вид наших приложений?)
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
потом указать на этот пользовательский селектор.