How to Change the Color of a Switchcompat from Appcompat Library

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 with android:
  • 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 the Theme.MaterialComponents (like colorSecondary, colorSurface and colorOnSurface) 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



Leave a reply



Submit