SwitchPreferenceCompat still retains the old Switch style, I know to be able to style it Material 3 in the following way:
theme.xml
<style name="Theme.Material3.Preference" parent="Theme.Material3.DayNight.NoActionBar">
<item name="preferenceTheme">@style/MaterialPreferenceThemeOverlay</item>
</style>
<style name="MaterialPreferenceThemeOverlay" parent="PreferenceThemeOverlay">
<item name="switchPreferenceCompatStyle">@style/Preference.SwitchPreferenceCompat</item>
</style>
<style name="Preference.SwitchPreferenceCompat" parent="Preference.SwitchPreferenceCompat.Material">
<item name="android:widgetLayout">@layout/preference_widget_material_switch</item>
</style>
preference_widget_material_switch.xml
<?xml version="1.0" encoding="utf-8"?>
<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:focusable="false"
android:clickable="false"
android:background="@null"/>
setting.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreferenceCompat
android:defaultValue="true"
android:key="pref_key"
android:summary="Preference Summary"
android:title="Preference Title" />
</PreferenceScreen>

But for some reason I have to build PreferenceFragment programmatically like this:
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
val context = preferenceManager.context
val screen = preferenceManager.createPreferenceScreen(context)
val notificationPreference = SwitchPreferenceCompat(context).apply {
key = "pref_key"
title = "Preference Title"
summary="Preference Summary"
}
screen.addPreference(notificationPreference)
preferenceScreen = screen
}
At this time, even if I have the ThemeOverlay above, the style of the switch is still old.

So, how to use material 3 Switch in PreferenceFragmentCompat programmatically?
I'm guessing it might be possible to set the theme of SwitchPreferenceCompat via one of its constructors, but I don't know about Views, so can you guys help me?
SwitchPreferenceCompat(@NonNull Context context)
SwitchPreferenceCompat(
@NonNull Context context,
@Nullable AttributeSet attrs
)
SwitchPreferenceCompat(
@NonNull Context context,
@Nullable AttributeSet attrs,
int defStyleAttr
)
SwitchPreferenceCompat(
@NonNull Context context,
@Nullable AttributeSet attrs,
int defStyleAttr,
int defStyleRes
)
If you don't want to add a new class for the Material 3 switches, you can override the used layout of the usual SwitchPreferenceCompat by following 2 simple steps:
https://medium.com/@cyb3rko/simple-implementation-of-material-3-switches-in-preferences-4b83ea3202d1
<?xml version="1.0" encoding="utf-8"?>
<!-- Derived from https://github.com/androidx/androidx/blob/005e9694795cee9a42375d80b0d813af9e700ac1/preference/preference/res/layout/preference_widget_switch_compat.xml -->
<!-- Thanks to https://stackoverflow.com/a/73782598/9077356 -->
<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:focusable="false"
android:clickable="false"
android:background="@null" />
<?xml version="1.0" encoding="utf-8"?>
<resources>
...
<style name="Preference.SwitchPreferenceCompat" parent="@style/Preference.SwitchPreferenceCompat.Material"
tools:ignore="ResourceCycle">
<item name="widgetLayout">@layout/preference_switch</item>
</style>
...
</resources>
Now you can just use the usual SwitchPreferenceCompat in your preference screen like before:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:app="http://schemas.android.com/apk/res-auto">
<SwitchPreferenceCompat
app:title="Material 3 switch"
app:summary="This is the new Material 3 switch" />
</PreferenceScreen>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With