I\'ve tried using the following link to change the color of a SwitchCompat:
How to change the color of a SwitchCompat
Notice the low constrast in my switch:<
just use colorControlActivated to set the color of SwitchCompat's track and thumb.
If not set, the default colorControlActivated color will use colorAccent. (from the experience, still not find where in the source code).
The source code changed and does not still like @Ovidiu said. But still thanks him for let me know to find the answer from the source code.
mThumbDrawable = a.getDrawable(R.styleable.SwitchCompat_android_thumb);
will eventually call the following method.
/frameworks/support/v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java
private ColorStateList createSwitchTrackColorStateList(Context context) {
final int[][] states = new int[3][];
final int[] colors = new int[3];
int i = 0;
// Disabled state
states[i] = ThemeUtils.DISABLED_STATE_SET;
colors[i] = getThemeAttrColor(context, android.R.attr.colorForeground, 0.1f);
i++;
states[i] = ThemeUtils.CHECKED_STATE_SET;
colors[i] = getThemeAttrColor(context, R.attr.colorControlActivated, 0.3f);
i++;
// Default enabled state
states[i] = ThemeUtils.EMPTY_STATE_SET;
colors[i] = getThemeAttrColor(context, android.R.attr.colorForeground, 0.3f);
i++;
return new ColorStateList(states, colors);
}
private ColorStateList createSwitchThumbColorStateList(Context context) {
final int[][] states = new int[3][];
final int[] colors = new int[3];
int i = 0;
final ColorStateList thumbColor = getThemeAttrColorStateList(context,
R.attr.colorSwitchThumbNormal);
if (thumbColor != null && thumbColor.isStateful()) {
// If colorSwitchThumbNormal is a valid ColorStateList, extract the default and
// disabled colors from it
// Disabled state
states[i] = ThemeUtils.DISABLED_STATE_SET;
colors[i] = thumbColor.getColorForState(states[i], 0);
i++;
states[i] = ThemeUtils.CHECKED_STATE_SET;
colors[i] = getThemeAttrColor(context, R.attr.colorControlActivated);
i++;
// Default enabled state
states[i] = ThemeUtils.EMPTY_STATE_SET;
colors[i] = thumbColor.getDefaultColor();
i++;
} else {
// Else we'll use an approximation using the default disabled alpha
// Disabled state
states[i] = ThemeUtils.DISABLED_STATE_SET;
colors[i] = getDisabledThemeAttrColor(context, R.attr.colorSwitchThumbNormal);
i++;
states[i] = ThemeUtils.CHECKED_STATE_SET;
colors[i] = getThemeAttrColor(context, R.attr.colorControlActivated);
i++;
// Default enabled state
states[i] = ThemeUtils.EMPTY_STATE_SET;
colors[i] = getThemeAttrColor(context, R.attr.colorSwitchThumbNormal);
i++;
}
return new ColorStateList(states, colors);
}
If you want a more switches in multiple colors in one Activity, you can use this solution (based on theme by @Konifar):
<style name="CustomSwitchTheme" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<!-- Active thumb color & Active track color(30% transparency) -->
<item name="colorControlActivated">@color/custom</item>
<!-- Inactive thumb color -->
<item name="colorSwitchThumbNormal">#E0E0E0</item>
<!-- Inactive track color(30% transparency) -->
<item name="android:colorForeground">#757575</item>
</style>
where @color/custom
is color of thumb when switch is activated.
Then apply this theme to your SwitchCompat this way:
<android.support.v7.widget.SwitchCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="@style/CustomSwitchTheme" />
I was having the same problem. Finally solved it programatically with this Kotlin code
fun tintSwitchButton(sw: SwitchCompat, resolvedColor: Int) {
val states = arrayOf(
intArrayOf(-android.R.attr.state_pressed),
intArrayOf(android.R.attr.state_pressed)
)
DrawableCompat.setTintList(sw?.trackDrawable, ColorStateList(
states,
intArrayOf(resolvedColor, resolvedColor)
))
DrawableCompat.setTintList(sw?.thumbDrawable, ColorStateList(
states,
intArrayOf(Color.WHITE, Color.WHITE)
))
}
And the function call is
tintSwitchButton(switchCompat, Color.rgb(214, 0, 0))
You can also create an extension function:
fun SwitchCompat.tint(resolvedColor: Int) {
val states = arrayOf(
intArrayOf(-android.R.attr.state_pressed),
intArrayOf(android.R.attr.state_pressed)
)
DrawableCompat.setTintList(trackDrawable, ColorStateList(
states,
intArrayOf(resolvedColor, resolvedColor)
))
DrawableCompat.setTintList(thumbDrawable, ColorStateList(
states,
intArrayOf(Color.WHITE, Color.WHITE)
))
}
So the call would be easier
switchCompat.tint(Color.rgb(214,0,0))
Here is how a developer can change the track drawable of a SwitchCompat:
First, in the root layout, write xmlns:SwitchCompat="http://schemas.android.com/apk/res-auto"
Then:
<android.support.v7.widget.SwitchCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:thumb="@drawable/your_switch_thumb"
SwitchCompat:track="@drawable/your_switch_track_selector"
/>
where your_switch_track_selector can be:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/switch_ios_track_on" android:state_checked="true" />
<item android:drawable="@drawable/switch_ios_track_off" android:state_checked="false" />
</selector>
1.switch_ios_track_on:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<solid android:color="#4EDA62" />
<corners android:radius="20dp" />
</shape>
2.switch_ios_track_off:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<solid android:color="#E3E3E3" />
<corners android:radius="20dp" />
</shape>
Simple and easy..
With the MaterialSwitch
provided by the Material Components Library.
materialThemeOverlay
attribute to override the app color for the Switch. <style name="CustomWidget.MaterialComponents.CompoundButton.Switch" parent="Widget.MaterialComponents.CompoundButton.Switch">
<item name="materialThemeOverlay">@style/CustomCompoundButton_Switch</item>
</style>
<style name="CustomCompoundButton_Switch" >
<item name="colorSurface">@color/yellow</item>
<item name="colorOnSurface">@color/orange</item>
<item name="colorControlActivated">@color/blue</item>
</style>
And in the layout:
<com.google.android.material.switchmaterial.SwitchMaterial
style="@style/Widget.MaterialComponents.CompoundButton.Switch"
../>
style
attribute: <style name="CustomStyleWidget.MaterialComponents.CompoundButton.Switch"
parent="Widget.MaterialComponents.CompoundButton.Switch">
<item name="useMaterialThemeColors">false</item>
<item name="trackTint">@color/track_selector</item>
<item name="thumbTint">@color/thumb_selector</item>
</style>
with thumb_selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="@color/switchTrackDisable"/>
<item android:state_checked="true" android:color="@color/switchThumbActive" />
<item android:color="@color/switchThumbkNormal" />
</selector>
and track_selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="@color/switchTrackDisable"/>
<item android:state_checked="true" android:color="@color/switchTrackActive" />
<item android:color="@color/switchTrackNormal" />
</selector>
And in the layout:
<com.google.android.material.switchmaterial.SwitchMaterial
style="@style/CustomStyleWidget.MaterialComponents.CompoundButton.Switch"
../>
Below is the AppCompat way of changing both the track and thumb color programmatically, for a specific SwitchCompat. For this example, I have hardcoded the thumbColor
to red. Ideally, you would set the color through a second method parameter.
Please note that when the switch is checked, a ripple is displayed. The ripple color will not be changed by the code below.
public static void setSwitchColor(SwitchCompat v) {
// thumb color of your choice
int thumbColor = Color.RED;
// trackColor is the thumbColor with 30% transparency (77)
int trackColor = Color.argb(77, Color.red(thumbColor), Color.green(thumbColor), Color.blue(thumbColor));
// setting the thumb color
DrawableCompat.setTintList(v.getThumbDrawable(), new ColorStateList(
new int[][]{
new int[]{android.R.attr.state_checked},
new int[]{}
},
new int[]{
thumbColor,
Color.WHITE
}));
// setting the track color
DrawableCompat.setTintList(v.getTrackDrawable(), new ColorStateList(
new int[][]{
new int[]{android.R.attr.state_checked},
new int[]{}
},
new int[]{
trackColor,
Color.parseColor("#4D000000") // full black with 30% transparency (4D)
}));
}