So i'm updating my apps to fully support Monet and Material You guidelines, and the official site mentions a new design for the switches. I used it, and that's the result:
I have a preference screen using Androidx preferences library, latest version available at the time of writing, and the only way i found to theme the switches (except the manual theming, which makes no sense) is to use this line in the app's theme:
<item name="switchStyle">@style/Widget.Material3.CompoundButton.MaterialSwitch</item>
And using SwitchPreferenceCompat (it doesn't work in the regular SwitchPreference) this is what i get:
Regardless of the width (which is different, but can be changed) the disabled state is completely different and doesn't match the rest of the app. Why? and most importantly, why do they suggest to use a library which:
?
I don't want to be too critical, but this is out of my understanding.
EDIT: at the moment, i'm using switchCompat everywhere, to make the app uniform. Looking at the system apps, i can find 4 different type of switches: a custom switch similar to the second screenshot, the old one and the two types in this question. That's hella confusing.
I understand Google stance on this, they don't want to make androidx.*
packages dependent to Material library itself, maybe they should provide a separate preference package but this time with fully Material widgets.
In order to have the brand new MaterialSwitch of Material 1.7.0 with preference, I've overridden its widgetLayout
with a custom layout by android:widgetLayout="@layout/preference_material_switch"
(in fact I applied that programmatically like .widgetLayoutResource = R.layout.preference_material_switch
) and put the following on preference_material_switch.xml layout file,
<?xml version="1.0" encoding="utf-8"?>
<!-- Derived from https://github.com/androidx/androidx/blob/8cb282cc/preference/preference/res/layout/preference_widget_switch_compat.xml -->
<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:background="@null"
android:clickable="false"
android:focusable="false" />
Update: Alternative solution rather than adding android:widgetLayout=
to each switch is to add the following to your base theme,
<item name="preferenceTheme">@style/AppPreferenceThemeOverlay</item>
Then adding the following styles also,
<style name="AppPreferenceThemeOverlay" parent="@style/PreferenceThemeOverlay">
<item name="switchPreferenceCompatStyle">@style/AppSwitchPreference</item>
</style>
<style name="AppSwitchPreference" parent="@style/Preference.SwitchPreferenceCompat.Material">
<item name="widgetLayout">@layout/preference_material_switch</item>
</style>
And here is the result,