如何在PreferenceFragmentCompat中以代码方式使用Material 3 Switch?
代码构建PreferenceFragmentCompat时如何启用Material 3风格的SwitchPreferenceCompat
背景
我已了解通过XML配置可让SwitchPreferenceCompat使用Material 3风格:
1. 主题配置(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>
2. 自定义Switch布局(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"/>
3. XML定义Preference(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>
通过XML配置时,Switch能正常显示Material 3样式,但当我用代码构建PreferenceFragment时:
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 }
即便配置了主题,Switch还是旧版样式。
问题
如何在PreferenceFragmentCompat中通过代码方式使用Material 3风格的Switch?
我猜测可能需要通过SwitchPreferenceCompat的构造函数指定主题,但对视图相关知识不太熟悉,希望得到解答。SwitchPreferenceCompat的构造函数如下:
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 )
解决方案
方案1:用主题包装Context创建SwitchPreferenceCompat
直接使用preferenceManager.context可能未应用自定义的Preference主题,通过ContextThemeWrapper包装上下文,传入我们定义的MaterialPreferenceThemeOverlay主题:
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { val originalContext = preferenceManager.context // 用自定义Preference主题包装上下文 val themedContext = ContextThemeWrapper(originalContext, R.style.MaterialPreferenceThemeOverlay) val screen = preferenceManager.createPreferenceScreen(originalContext) val notificationPreference = SwitchPreferenceCompat(themedContext).apply { key = "pref_key" title = "Preference Title" summary = "Preference Summary" } screen.addPreference(notificationPreference) preferenceScreen = screen }
方案2:构造函数传入自定义样式参数
利用SwitchPreferenceCompat的多参构造函数,直接指定自定义的样式属性和资源:
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { val context = preferenceManager.context val screen = preferenceManager.createPreferenceScreen(context) val notificationPreference = SwitchPreferenceCompat( context, null, androidx.preference.R.attr.switchPreferenceCompatStyle, // 指定系统样式属性 R.style.Preference_SwitchPreferenceCompat // 传入我们自定义的样式 ).apply { key = "pref_key" title = "Preference Title" summary = "Preference Summary" } screen.addPreference(notificationPreference) preferenceScreen = screen }
方案3:给宿主Activity指定正确主题
在AndroidManifest.xml中,给PreferenceFragmentCompat所在的Activity设置Theme.Material3.Preference主题,这样preferenceManager.context会自动继承该主题,代码创建的SwitchPreferenceCompat也会应用Material 3样式:
<activity android:name=".YourPreferenceActivity" android:theme="@style/Theme.Material3.Preference"> </activity>
内容的提问来源于stack exchange,提问作者bqliang
相关产品推荐
相关产品推荐

