'Change "on" color of a Switch
I'm using a standard Switch control with the holo.light theme in a ICS app.
I want to change the highlighted or on state color of the Toggle Button from the standard light blue to green.
This should be easy, but I can't seem to work out how to do it.
Solution 1:[1]
Late to party but this is how I did
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>
Colors
Layout
<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" />
Result
See change of colors for enables and disabled switch
Solution 2:[2]
This is working for me (requires 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);
Note that the "default" state needs to be added last as shown here.
The only problem I see is that the "thumb" of the switch now appears larger than the background or "track" of the switch. I think that's because I'm still using the default track image, which has some empty space around it. However, when I attempted to customize the track image using this technique, my switch appeared to have a height of 1 pixel with just a sliver of the on/off text appearing. There must be a solution for that, but I haven't found it yet...
Update for Android 5
In Android 5, the code above makes the switch disappear completely. We should be able to use the new setButtonTintList method, but this seems to be ignored for switches. But this works:
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);
Update for Android 6-7
As Cheruby stated in the comments, we can use the new setThumbTintList
and that worked as expected for me. We can also use setTrackTintList
, but that applies the color as a blend, with a result that's darker than expected in dark color themes and lighter than expected in light color themes, sometimes to the point of being invisible. In Android 7, I was able to minimize that change that by overriding the track tint mode, but I couldn't get decent results from that in Android 6. You might need to define extra colors that compensate for the blending. (Do you ever get the feeling that Google doesn't want us to customize the appearance of our apps?)
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);
}
Solution 3:[3]
To change Switch style without using style.xml or Java code, you can customize switch into layout XML :
<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" />
It's attribute android:thumbTint and android:trackTint that allowed you to customize color
This is the visual result for this XML :
Solution 4:[4]
As an addition to existing answers: you can customize thumb and track using selectors in res/color
folder, for example:
switch_track_selector
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/lightBlue"
android:state_checked="true" />
<item android:color="@color/grey"/>
</selector>
switch_thumb_selector
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/darkBlue"
android:state_checked="true" />
<item android:color="@color/white"/>
</selector>
Use these selectors to customize track and thumb tints:
<androidx.appcompat.widget.SwitchCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:trackTint="@color/switch_track_selector"
app:thumbTint="@color/switch_thumb_selector"/>
Keep in mind that if you use standart Switch
and android
namespace for these attributes, it will only work for API 23 and later, so use SwitchCompat
with app
namespace xmlns:app="http://schemas.android.com/apk/res-auto"
as universal solution.
Result:
Solution 5:[5]
Create a custom Switch and override setChecked to change color:
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();
}
}
}
}
Solution 6:[6]
<androidx.appcompat.widget.SwitchCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:thumbTint="@color/white"
app:trackTint="@drawable/checker_track"/>
And inside 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>
Solution 7:[7]
make drawable "newthumb.xml"
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/Green" android:state_checked="true"/>
<item android:color="@color/Red" android:state_checked="false"/>
</selector>
and make drawable "newtrack.xml"
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/black" android:state_checked="true"/>
<item android:color="@color/white" android:state_checked="false"/>
</selector>
and add it in Switch:
<Switch
android:trackTint="@drawable/newtrack"
android:thumbTint="@drawable/newthumb"
/>
Use app:trackTint
and app:thumbTint
instead for switch compat androidx – see @Ehsan Rosdi's comments.
Also, it's perfectly OK to make only one drawable file ("switchcolors.xml") and use that for both trackTint and thumbTint.
Solution 8:[8]
While answer by SubChord is correct, is doesnt really answer the question of how to set the "on" color without also affecting other widgets. To do this, use a ThemeOverlay
in styles.xml:
<style name="ToggleSwitchTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="colorAccent">@color/green_bright</item>
</style>
And reference it in your switch:
<android.support.v7.widget.SwitchCompat
android:theme="@style/ToggleSwitchTheme" ... />
In so doing it will ONLY affect the color of the views you want to apply it to.
Solution 9:[9]
I solved it by updating the Color Filter when the Switch was state was changed...
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);
}
}
Solution 10:[10]
May be its a bit late, but for switch buttons, toogle button is not the answer, you must change the drawable in the xml parameter of the switch:
android:thumb="your drawable here"
Solution 11:[11]
In Android Lollipop and above, define it in your theme style:
<style name="BaseAppTheme" parent="Material.Theme">
...
<item name="android:colorControlActivated">@color/color_switch</item>
</style>
Solution 12:[12]
Create your own 9-patch image and set it as the background of the toggle button.
Solution 13:[13]
This worked for me -:
1.code in values/styles.xml -:
<style name="SwitchTheme" parent="Theme.AppCompat.Light">
<item name="android:colorControlActivated">#148E13</item>
</style>
2.add following line of code in your switch in your layout file -:
android:theme="@style/SwitchTheme"
Solution 14:[14]
The solution suggested from arlomedia worked for me. About his issue of extraspace I solved removing all the paddings to the switch.
EDIT
As requested, here what I have.
In the layout file, my switch is inside a linear layout and after a 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>
Since I'm working with Xamarin / Monodroid (min. Android 4.1) my code is:
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 is previously defined like this (Xamarin):
Switch swtch_EnableEdit = view.FindViewById<Switch>(Resource.Id.mySwitch);
I don't set at all the paddings and I don't call .setPadding(0, 0, 0, 0).
Solution 15:[15]
Easiest way is defining track tint, and setting tint mode to src_over to remove 30% transparency.
android:trackTint="@drawable/toggle_style"
android:trackTintMode="src_over"
toggle_style.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/informationDefault"
android:state_checked="true"
/>
<item android:color="@color/textDisabled" android:state_checked="false"/>
</selector>
Solution 16:[16]
you can make custom style for switch widget that use color accent as a default when do custom style for it
<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>
Solution 17:[17]
You can try this lib, easy to change color for the switch button.
https://github.com/kyleduo/SwitchButton
Solution 18:[18]
Try to find out right answer here: Selector on background color of TextView. In two words you should create Shape in XML with color and then assign it to state "checked" in your selector.
Solution 19:[19]
I dont know how to do it from java , But if you have a style defined for your app you can add this line in your style and you will have the desired color for me i have used #3F51B5
<color name="ascentColor">#3F51B5</color>
Solution 20:[20]
In xml , you can change the color as :
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/notificationSwitch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checked="true"
app:thumbTint="@color/darkBlue"
app:trackTint="@color/colorGrey"/>
Dynamically you can change as :
Switch.thumbDrawable.setColorFilter(ContextCompat.getColor(requireActivity(), R.color.darkBlue), PorterDuff.Mode.MULTIPLY)
Solution 21:[21]
Based on a combination of a few of the answers here this is what worked for me.
<Switch
android:trackTintMode="src_over"
android:thumbTint="@color/white"
android:trackTint="@color/shadow"
android:checked="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Solution 22:[22]
Change the tint colour for track and thumb drawable.
switch.getThumbDrawable().setTint(ContextCompat.getColor(this,R.color.colorAccent));
switch.getTrackDrawable().setTint(ContextCompat.getColor(this,R.color.colorAccent));
Solution 23:[23]
Android 2022 - most simple and straightforward method:
change in
/res/values/themes.xml
FROM
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
TO
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/purple_500</item>
<item name="colorSecondaryVariant">@color/purple_700</item>
Solution 24:[24]
Programattically if you want to change Switch Component Color use this code below:
binding.switchCompatBackupMedia.thumbTintList =
ColorStateList.valueOf(Color.parseColor("#00C4D3"))
binding.switchCompatBackupMedia.trackTintList =
ColorStateList.valueOf(Color.parseColor("#00C4D31F"))
Solution 25:[25]
Solution for Android Studio 3.6:
yourSwitch.setTextColor(getResources().getColor(R.color.yourColor));
Changes the text color of a in the color XML file defined value (yourColor).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow