Change "on" color of a Switch
Asked Answered
D

27

232

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.

Danedanegeld answered 28/6, 2012 at 21:57 Comment(2)
I don't really see any other way than copying the relevant platform resources (selector and *.png files) and modify the 'on' state drawable. Don't forget to point the Switch to this custom selector afterwards.Thera
2021 for anyone googling this very old question, it is now very easy, answer of @مهند عطية below https://mcmap.net/q/117285/-change-quot-on-quot-color-of-a-switchSchnook
R
128

As of now it is better to use SwitchCompat from the AppCompat.v7 library. You can then use simple styling to change the color of your components.

values/themes.xml:

<style name="Theme.MyTheme" parent="Theme.AppCompat.Light">
    <!-- colorPrimary is used for the default action bar background -->
    <item name="colorPrimary">@color/my_awesome_color</item>

    <!-- colorPrimaryDark is used for the status bar -->
    <item name="colorPrimaryDark">@color/my_awesome_darker_color</item>

    <!-- colorAccent is used as the default value for colorControlActivated,
         which is used to tint widgets -->
    <item name="colorAccent">@color/accent</item>

    <!-- You can also set colorControlNormal, colorControlActivated
         colorControlHighlight, and colorSwitchThumbNormal. -->

</style>

ref: Android Developers Blog

EDIT:

The way in which it should be correctly applied is through android:theme="@style/Theme.MyTheme" and also this can be applied to parent styles such as EditTexts, RadioButtons, Switches, CheckBoxes and ProgressBars:

<style name="My.Widget.ProgressBar" parent="Widget.AppCompat.ProgressBar">

<style name="My.Widget.Checkbox" parent="Widget.AppCompat.CompoundButton.CheckBox">
Raquelraquela answered 3/11, 2014 at 10:41 Comment(9)
Although not applicable at the time, this should be the accepted answer!Costmary
Have changed this to the accepted answer, as it seems the more "modern" approach to this question.Danedanegeld
I tried all of these and none of them changed the color of the "on" state for my switch.Georgie
'on' is colorAccent, 'off' is colorSwitchThumbNormal. If using the AppCompat theme, you need to use SwitchCompat rather than Switch. If using SDK 23+, you can use android:thumbTint and android:thumbTintMode with a ColorStateList.Addict
@Addict plz reply will those 'android:thumbTint' things will work on devices < 23Benghazi
Would anyone suspect this not to work when my app's base them includes a "colorAccent" field with a different value? I am trying to make an active switch (with "colorAccent") blue when the base theme "colorAccent" is pink. It looks like I am unable to "overwrite" the pink color from the base theme, which is not what I would expect.Kurdish
Note that this didn't won't work for me when I had SwitchCompat instead of switch. Took me a while to figure it out. hopefully it helps someone else.Blackout
the texton and textoff colors change as well, how do i set them to different color?Canescent
This fixed it: <item name="colorControlActivated">@color/black</item> <!-- Inactive thumb color --> <item name="colorSwitchThumbNormal">@color/black</item> <!-- Inactive track color(30% transparency) --> <item name="android:colorForeground">@color/white</item>Canescent
S
335

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

enter image description here

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

enter image description here

Schiff answered 9/7, 2016 at 5:1 Comment(7)
@MaksimKniazev You have to use SwitchCompat ;)Baroja
Good, except of colorControlActivated - it doesn't set track color, only thumb color.Supersaturated
here is solution for Switch and SwitchCompat: https://mcmap.net/q/119776/-unable-to-change-switch-colorEjector
<style> tags needed to be written under res>>values>>styles.xml and on XML page for <Switch ...> you should add only the line called: android:theme="@style/SCBSwitch and my colors are: colorControlActivated">#ff0000 and colorSwitchThumbNormal">#00ff00 and android:colorForeground">#00ff00Lueck
@OviTrif Awesome! It is impressive how hard it is to find a simple information like that. Lots and lots of answers I've been reading, and nobody, gave a working answer until now. Finally!Dibbell
Perfect. Worked like a charm.Lakesha
If inactive track's color is not being changed with above style's item, give it a try: <item name="colorControlNormal">#000000</item>Ulu
R
128

As of now it is better to use SwitchCompat from the AppCompat.v7 library. You can then use simple styling to change the color of your components.

values/themes.xml:

<style name="Theme.MyTheme" parent="Theme.AppCompat.Light">
    <!-- colorPrimary is used for the default action bar background -->
    <item name="colorPrimary">@color/my_awesome_color</item>

    <!-- colorPrimaryDark is used for the status bar -->
    <item name="colorPrimaryDark">@color/my_awesome_darker_color</item>

    <!-- colorAccent is used as the default value for colorControlActivated,
         which is used to tint widgets -->
    <item name="colorAccent">@color/accent</item>

    <!-- You can also set colorControlNormal, colorControlActivated
         colorControlHighlight, and colorSwitchThumbNormal. -->

</style>

ref: Android Developers Blog

EDIT:

The way in which it should be correctly applied is through android:theme="@style/Theme.MyTheme" and also this can be applied to parent styles such as EditTexts, RadioButtons, Switches, CheckBoxes and ProgressBars:

<style name="My.Widget.ProgressBar" parent="Widget.AppCompat.ProgressBar">

<style name="My.Widget.Checkbox" parent="Widget.AppCompat.CompoundButton.CheckBox">
Raquelraquela answered 3/11, 2014 at 10:41 Comment(9)
Although not applicable at the time, this should be the accepted answer!Costmary
Have changed this to the accepted answer, as it seems the more "modern" approach to this question.Danedanegeld
I tried all of these and none of them changed the color of the "on" state for my switch.Georgie
'on' is colorAccent, 'off' is colorSwitchThumbNormal. If using the AppCompat theme, you need to use SwitchCompat rather than Switch. If using SDK 23+, you can use android:thumbTint and android:thumbTintMode with a ColorStateList.Addict
@Addict plz reply will those 'android:thumbTint' things will work on devices < 23Benghazi
Would anyone suspect this not to work when my app's base them includes a "colorAccent" field with a different value? I am trying to make an active switch (with "colorAccent") blue when the base theme "colorAccent" is pink. It looks like I am unable to "overwrite" the pink color from the base theme, which is not what I would expect.Kurdish
Note that this didn't won't work for me when I had SwitchCompat instead of switch. Took me a while to figure it out. hopefully it helps someone else.Blackout
the texton and textoff colors change as well, how do i set them to different color?Canescent
This fixed it: <item name="colorControlActivated">@color/black</item> <!-- Inactive thumb color --> <item name="colorSwitchThumbNormal">@color/black</item> <!-- Inactive track color(30% transparency) --> <item name="android:colorForeground">@color/white</item>Canescent
B
67

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:

enter image description here

Binnings answered 5/6, 2020 at 7:6 Comment(2)
I don't have res/color folderCanescent
Neither did I - my colors were stored in res/values/colors.xml. However, if you create res/colors and add the two selector XMLs you'll still be able to reference them using @colorNomi
B
53

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);
}
Balmung answered 3/9, 2014 at 2:56 Comment(4)
I'm using the getThumbDrawable/getTrackDrawable approach to create a switch where both states have the same color - in other words, the switch doesn't enable/disable something, but is used for a choice between two alternatives.Handicraft
Got that DrawableCompat.setTintList will allow it to work on previous devices. I call: DrawableCompat.setTintList(switchCompat.getThumbDrawable(), foregroundState);Covert
Please edit the answer to include the DrawableCompat solution. It works perfectly!Villosity
API 23+: switchInput.setThumbTintList(buttonStates); works for Nougat as well. API 21-22: Use the DrawableCompat as suggested by @Alexey. The switchInput.setButtonTintList(buttonStates); didn't work for me, it didn't color the states for my Switch. API below 21: switchInput.getThumbDrawable().setColorFilter(someColor, PorterDuff.Mode.SrcIn); These worked for me. I worked with Xamarin as well, so translate those to C# in the Android renderers if you use Xamarin.Forms.Spannew
F
53

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.

Fatshan answered 13/10, 2019 at 9:46 Comment(7)
This works. However, it should be noted that AndroidStudio will not be able to suggest @drawable resources for trackTint or thumbTint. One needs to write it in manually and it works.Johannesburg
For some reason this is the only answer that works reliably on my Huawei. Thanks!Standing
THANKS YOU SO MUCHSchnook
SENT A BOUNTY !Schnook
use app:trackTint and app:thumbTint instead for switch compat androidxInductive
@EhsanRosdi you should add your comment as an answer. I spent a couple minutes scrolling and reading before I came upon your comment.Lianneliao
trackTint is a color, you can't set a drawable to it.Butterbur
S
51

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 :

enter image description here

Speaker answered 14/9, 2016 at 8:45 Comment(6)
This changes the color of the thumb, no matter if it's turned on or off.Keim
"Attribute thumbTint is only used in API level 21 and higher"Knesset
@Knesset use app:thumbTint and app:trackTint with the SwitchCompat from the AppCompat.v7 library for a lower API level.Atelectasis
That works, but what if you want to change the color for thumb, depending on whether it's on or off?Ops
If you want to use thumbTint below 21 the use app:thumbTint instead of android:thumbTint and change switch with SwitchCompatStour
@TavernSenses for differentiating the color between on and off apply a color state list to the tint property, one color for state_checked="true" and another for falseFissure
G
37

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();
            }
        }
    }
}
Glassy answered 15/7, 2015 at 18:6 Comment(2)
The first post that actually helped me achieved custom color for the Material Switch without using style or themes. Thanks !Harlotry
Nice. I already had my own customized Switch, so I've only had to override the setChecked method and all of them automatically changed their colors. Thanks from Spain.Baptist
F
35
<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>
Frisbie answered 20/3, 2019 at 16:30 Comment(3)
thumbTint only applies on Android API 21 and above. How if i want to change the colour on below Android 21?Ogren
developer.android.com/reference/android/support/v7/widget/… SwitchCompat is backward compatible with API 7 and aboveFrisbie
It is 2020. I really wonder where in the world people still using Android 21 and below?Jackijackie
I
33

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.

Ignominy answered 25/5, 2016 at 16:2 Comment(1)
For some reason, I also had to set "colorControlActivated" to the same value, yet on POC, it was enough to use "colorAccent". How come?Keim
P
20

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);
    }
}
Pity answered 11/8, 2015 at 18:42 Comment(0)
A
12

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"
Aretino answered 3/7, 2013 at 22:45 Comment(0)
A
10

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"
Acorn answered 15/10, 2020 at 18:1 Comment(1)
Best and simple solutionHeadman
E
9

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>
Eustatius answered 28/1, 2016 at 10:24 Comment(3)
The problem with this solution is that it also changes the colors of my selected textedits which is not what I want.Yours
@Yours Of course it will. Because this is set in global style preference. In order to achieve your goal, is to find the view id of your target view and modify its attributes.Eustatius
OK, that's for the "On" position. What about changing the thumb color for the "Off" position?Ops
B
6

Create your own 9-patch image and set it as the background of the toggle button.

http://radleymarx.com/2011/simple-guide-to-9-patch/

Breastpin answered 28/6, 2012 at 22:9 Comment(5)
Yeah, could do that, but surely there MUST be an easier way? Selectors maybe?Danedanegeld
No, there is no easier way. You can't magically change the color of an image :)Breastpin
Good point. I didn't fully get how it worked until I had a deeper look.Danedanegeld
@Denizen, Are you sure? If so, post an answer and I'll vote it up.Breastpin
@Denizen Please remove your comment. Android Switch always returns null for getBackground(), I wasted 30 minutes trying this.Benghazi
D
5

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).

Dartmoor answered 25/2, 2015 at 17:36 Comment(2)
Can you provide code for that? I tried switchInput.setPadding(0, 0, 0, 0) but nothing changed.Balmung
Tested in Xamarin using the AppCompat library to target 5.x and this worked as advertised.Wampum
B
5

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>
Balling answered 28/4, 2020 at 10:33 Comment(0)
E
4

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>    
Effort answered 3/10, 2017 at 7:49 Comment(0)
S
3

You can try this lib, easy to change color for the switch button.
https://github.com/kyleduo/SwitchButton enter image description here

Stanwinn answered 3/7, 2018 at 1:39 Comment(0)
T
1

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.

Thrown answered 11/7, 2013 at 10:6 Comment(2)
Nice solution, but do you know how can we change the color dynamically?Kibler
You just need to set the selector as the background resourceThrown
L
1

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>
Layoff answered 10/3, 2015 at 13:7 Comment(0)
G
1

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)
Genaro answered 2/7, 2020 at 14:45 Comment(0)
T
1

Based on a combination of a few of the answers here, this is what has 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"/>
Teran answered 16/8, 2020 at 7:39 Comment(0)
N
0

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));
Nutriment answered 29/1, 2022 at 6:8 Comment(0)
L
0

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"))
Legislature answered 26/4, 2022 at 13:20 Comment(0)
C
0

I'm android developer recently I have to maintain an old application, so I need to add Material Components 3 and update to androidx.core and androidx.appcompat. As you might understand my idea was to reuse the maximum code as I could. But I face some problems for example. Change the switch button color. I tried all the techniques I know and I follow all the answers in this thread.

So I found a solution by myself combining all the answers and suggestions here.

Lets start with the build.gradle file:

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
}

android {
    ...
    compileSdk 33

    defaultConfig {
        ...
        minSdk 21
        targetSdk 33
        versionCode 3004006
        versionName "3.4.6"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
    buildFeatures {
        viewBinding true
    }
    buildToolsVersion '32.0.0'
}

dependencies {
    implementation 'androidx.core:core-ktx:1.9.0'
    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.8.0'
    implementation 'androidx.compose.material3:material3:1.0.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    implementation 'androidx.navigation:navigation-fragment-ktx:2.5.3'
    implementation 'androidx.navigation:navigation-ui-ktx:2.5.3'
    implementation 'androidx.preference:preference:1.2.0'
    ...
}

We are using these dependencies and some configuration like minSdk 21 and targetSdk 33 so we can target almost 99% of the devices.

What I want is to change the color of the switch button defined in the preferences.xml file Originally I was using SwitchPreference but I couldn't change the color neither the thumb nor the track. I tried using custom colors modifying the colorPrimary and colorAccent or directly setting app:thumbTint and app:trackTint. Finally I decided to extend the SwitchPreference class. like this:

First create a new layout preference_material_switch.xml with for the MaterialSwitch

<com.google.android.material.materialswitch.MaterialSwitch xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/switchWidget"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:includeFontPadding="false"
    android:lineSpacingExtra="0dp"
    android:background="@null"
    android:clickable="false"
    android:focusable="false" />
class CustomSwitchPreference(context: Context, attrs: AttributeSet?) :
    SwitchPreference(context, attrs) {

    private var materialSwitch: MaterialSwitch? = null

    init {
        widgetLayoutResource = R.layout.preference_material_switch
    }

    override fun onBindViewHolder(holder: PreferenceViewHolder) {
        super.onBindViewHolder(holder)

        materialSwitch =
            holder.findViewById(androidx.preference.R.id.switchWidget) as MaterialSwitch?
        materialSwitch?.isChecked = isChecked
    }

    override fun onClick() {
        super.onClick()
        materialSwitch?.isChecked = isChecked
    }
}

The key points here are init here we assign preference_material_switch as the widget layout. Then we link the state of the switch with this code materialSwitch?.isChecked = isChecked

Then I modified the preferences.xml file:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <co.kr.rtt.kogas.station_manager.CustomSwitchPreference
        android:layout="@layout/custom_preference"
        android:defaultValue="true"
        android:key="notification_preference"
        android:title="@string/notification_preference_title"
        android:summaryOff="@string/notification_preference_summary_off"
        android:summaryOn="@string/notification_preference_summary_on" />
    <PreferenceCategory>
        <Preference
            android:layout="@layout/custom_preference"
            android:key="version_preference"
            android:summary="@string/app_version"
            android:title="@string/version_preference_title" />
        <Preference
            android:layout="@layout/custom_preference"
            android:key="privacy_policy"
            android:summary="@string/privacy_preference_summary"
            android:title="@string/privacy_preference_title" />
        <Preference
            android:layout="@layout/custom_preference"
            android:enabled="true"
            android:key="terms_of_service"
            android:summary="@string/tos_preference_summary"
            android:title="@string/tos_preference_title" />
    </PreferenceCategory>
</PreferenceScreen>

Here I setup a new layout: android:layout="@layout/custom_preference" for all the preferences. I found the source code of the Preferences layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?android:attr/selectableItemBackground"
    android:gravity="center_vertical"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:paddingEnd="?android:attr/scrollbarSize">

    <ImageView
        android:id="@android:id/icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="16dp" />

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="40dp"
        android:layout_marginTop="6dp"
        android:layout_marginEnd="6dp"
        android:layout_marginBottom="6dp"
        android:layout_weight="1"
        android:minHeight="64dp">

        <TextView
            android:id="@android:id/title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_toEndOf="@android:id/icon"
            android:includeFontPadding="false"
            android:lineSpacingExtra="0dp"
            android:maxLines="1"
            android:paddingTop="16dp"
            android:paddingEnd="16dp"
            android:textAppearance="?attr/textAppearanceTitleMedium"
            android:textStyle="bold"
            android:textColor="@color/accent" />

        <TextView
            android:id="@android:id/summary"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@android:id/title"
            android:layout_gravity="center_vertical"
            android:layout_toEndOf="@android:id/icon"
            android:lineSpacingExtra="0dp"
            android:maxLines="2"
            android:paddingEnd="16dp"
            android:textAppearance="?attr/textAppearanceLabelMedium"
            android:textColor="@color/dark" />

    </RelativeLayout>

    <LinearLayout
        android:id="@android:id/widget_frame"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:orientation="vertical" />
</LinearLayout>

Here I was able to change the color, font family, size, padding, etc. I got total control of the layout.

As you can se the LinearLayout instance with id widget_frame will be replaced with the MaterialSwitch instance.

I hope this will help you to have more control of your legacy apps.

Cockle answered 31/3, 2023 at 2:15 Comment(0)
D
-1

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>
Desman answered 16/3, 2022 at 12:58 Comment(0)
S
-2

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).

Splat answered 9/3, 2020 at 6:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.