How to change the color of a SwitchCompat from AppCompat library
AppCompat tinting attributs:
First, you should take a look to appCompat lib article there and to different attributs you can set:
colorPrimary: The primary branding color for the app. By default, this is the color applied to the action bar background.
colorPrimaryDark: Dark variant of the primary branding color. By default, this is the color applied to the status bar (via statusBarColor) and navigation bar (via navigationBarColor).
colorAccent: Bright complement to the primary branding color. By default, this is the color applied to framework controls (via colorControlActivated).
colorControlNormal: The color applied to framework controls in their normal state.
colorControlActivated: The color applied to framework controls in their activated (ex. checked, switch on) state.
colorControlHighlight: The color applied to framework control highlights (ex. ripples, list selectors).
colorButtonNormal: The color applied to framework buttons in their normal state.
colorSwitchThumbNormal: The color applied to framework switch thumbs in their normal state. (switch off)
If all custom switches are the same in a single activity:
With previous attributes you can define your own theme for each activity:
<style name="Theme.MyActivityTheme" 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>
and :
<manifest>
...
<activity
android:name=".MainActivity"
android:theme="@style/Theme.MyActivityTheme">
</activity>
...
</manifest>
If you want to have differents custom switches in a single activity:
As widget tinting in appcompat works by intercepting any layout inflation and inserting a special tint-aware version of the widget in its place (See Chris Banes post about it) you can not apply a custom style to each switch of your layout xml file. You have to set a custom Context that will tint switch with right colors.
--
To do so for pre-5.0 you need to create a Context that overlays global theme with customs attributs and then create your switches programmatically:
ContextThemeWrapper ctw = ContextThemeWrapper(getActivity(), R.style.Color1SwitchStyle);
SwitchCompat sc = new SwitchCompat(ctw)
As of AppCompat v22.1
you can use the following XML
to apply a theme to the switch widget:
<RelativeLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
...>
<android.support.v7.widget.SwitchCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:theme="@style/Color1SwitchStyle"/>
Your custom switch theme:
<style name="Color1SwitchStyle">
<item name="colorControlActivated">@color/my_awesome_color</item>
</style>
--
On Android 5.0 it looks like a new view attribut comes to life : android:theme
(same as one use for activity declaration in manifest). Based on another Chris Banes post, with the latter you should be able to define a custom theme directly on a view from your layout xml:
<android.support.v7.widget.SwitchCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="@style/Color1SwitchStyle"/>
To change the track color of a SwitchCompat
Thanks to vine'th I complete my answer with a link to SO answer that explains how to specify the Foreground of the Track when Switch is Off, it's there.
How to change the track color of a SwitchCompat
I had same probrem and solved it.
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
...
<!-- Active thumb color & Active track color(30% transparency) -->
<item name="colorControlActivated">@color/theme</item>
<!-- Inactive thumb color -->
<item name="colorSwitchThumbNormal">@color/grey300</item>
<!-- Inactive track color(30% transparency) -->
<item name="android:colorForeground">@color/grey600</item>
...
</style>
I read app compat code, and understand it.
android.support.v7.internal.widget.TintManager.java
private ColorStateList getSwitchTrackColorStateList() {
if (mSwitchTrackStateList == null) {
final int[][] states = new int[3][];
final int[] colors = new int[3];
int i = 0;
// Disabled state
states[i] = new int[] { -android.R.attr.state_enabled };
colors[i] = getThemeAttrColor(android.R.attr.colorForeground, 0.1f);
i++;
states[i] = new int[] { android.R.attr.state_checked };
colors[i] = getThemeAttrColor(R.attr.colorControlActivated, 0.3f);
i++;
// Default enabled state
states[i] = new int[0];
colors[i] = getThemeAttrColor(android.R.attr.colorForeground, 0.3f);
i++;
mSwitchTrackStateList = new ColorStateList(states, colors);
}
return mSwitchTrackStateList;
}
Change on color of a Switch
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">
Unable to change switch color
You're mixing styles and themes together.
These attributes are theme attributes so define them together in a theme overlay:
res/values/styles.xml (not values-v21)
<style name="ThemeOverlay.MySwitch" parent="">
<item name="android:colorControlActivated">@color/switch_color</item>
<item name="android:colorSwitchThumbNormal">#f1f1f1</item>
<item name="android:colorForeground">#42221f1f</item>
</style>
<style name="ThemeOverlay.MySwitchCompat" parent="">
<item name="colorControlActivated">@color/switch_color</item>
<item name="colorSwitchThumbNormal">#f1f1f1</item>
<item name="android:colorForeground">#42221f1f</item>
</style>
And then apply this theme overlay on the switch:
res/layout/layout.xml
<Switch
android:theme="@style/ThemeOverlay.MySwitch"/>
<androidx.appcompat.widget.SwitchCompat
android:theme="@style/ThemeOverlay.MySwitchCompat"/>
Pick one of the two variants:
Switch
available since API 21, all theme attributes are prefixed withandroid:
SwitchCompat
available in AndroidX AppCompat library, some theme attributes are not prefixed (make sure you know which).
How to change the thumb color of the switch in off state
Note: : Is deprecated: Its for android.support.V7.Widget.AppCompat, meaning it runs on devices back to API 7.
Use SwitchCompat from AppCompat or SwitchMaterial from material library as below:
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/trip_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="@style/SelectionSwitch"
android:switchMinWidth="56dp"
android:layout_marginStart="12dp"
android:checked="true"
android:textOff="nonrecc"
android:textOn="recc"/>
To change the color of the state: Change the color: #124964 for the different states
<style name="SelectionSwitch" parent="Theme.AppCompat.Light">
<item name="colorControlActivated">#FF0000</item>
<item name="colorSwitchThumbNormal">#000000</item>
<item name="android:colorForeground">#124964</item>
</style>
To change color when its in active state: (Example: am changing color to red when its active)
<item name="colorControlActivated">#FF0000</item>
To change color when its in off state: (Example: am changing color to black when its off)
<item name="colorSwitchThumbNormal">#00000</item>
Warning : Use SwitchCompat from AppCompat or SwitchMaterial from Material library
The SwitchMaterial
:
- is provided by the Material Components Library
- extends the
SwitchCompat
- uses
Widget.MaterialComponents.CompoundButton.Switch
as default style, using the colors defined in theTheme.MaterialComponents
(likecolorSecondary
,colorSurface
andcolorOnSurface
) and applying the Elevation Overlays in dark mode.
The SwitchCompat
:
- is provided by the androidx appcompat library
- uses
Widget.AppCompat.CompoundButton.Switch
as default style
By the way, why did they remove the Switch class?
The Switch
class is not removed. It is provided by the android framework like other widgets as Button
,TextView
.. and the appcompat and material components libraries provide an updated version of them (like AppCompatButton
, MaterialButton
...).
There is a different with these widgets.
Using an AppCompat
theme there is the AppCompatViewInflater
that automatically replaces all usages of core Android widgets inflated from layout files by the AppCompat extensions of those widgets (for example a Button
is replaced by AppCompatButton
).
Using the Theme.MaterialComponents
there is the MaterialComponentsViewInflater
that replaces some framework widgets with Material Components ones at inflation time, provided a Material Components theme is in use (for example a Button
is replaced by MaterialButton
).
It is NOT true for the SwitchMaterial
and the SwitchCompat
.The reason for that is due to the AppCompat SwitchCompat
not actually extending from the framework Switch
class.
Make switch stay same color when on and off
Add this to Styles.xml:
<style name="SelectionSwitch" parent="Theme.AppCompat.Light">
<!-- active thumb & track color (30% transparency) -->
<item name="colorControlActivated">#f1f1f1</item>
<!-- inactive thumb color -->
<item name="colorSwitchThumbNormal">#f1f1f1
</item>
<!-- inactive track color (30% transparency) -->
<item name="android:colorForeground">#42221f1f
</item>
</style>
and add the Switch to to your layout as below:
<android.support.v7.widget.SwitchCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="@style/SelectionSwitch" />
Related Topics
How to Copy Text to Clip Board in Android
How to Change the Color of a Switchcompat from Appcompat Library
Avoid Reloading Activity with Asynctask on Orientation Change in Android
How to Get the Width and Height of an Image View in Android
Android Kitkat Securityexception When Trying to Read from Mediastore
Mediarecorder and Videosource.Surface, Stop Failed: -1007 (A Serious Android Bug)
Is It Possible Query Data That Are Not Equal to the Specified Condition
Findviewbyid() Returns Null When I Call It in Oncreate()
Clicking Hamburger Icon on Toolbar Does Not Open Navigation Drawer
How to Force Stop My Android Application Programmatically
How to Evenly Distribute Buttons Across the Width of a Linearlayout
Android Studio Gradle Error: Multiple Dex Files Define
How to Set Up Dagger Dependency Injection from Scratch in Android Project
"Id Cannot Be Resolved or Is Not a Field" Error
Android Pending Intent Notification Problem