如何以编程方式使用 PreferenceFragmentCompat 中的材质 3 Switch?

bql*_*ang 7 xml android android-preferences material-components-android

SwitchPreferenceCompat 仍然保留了旧的 Switch 样式,我知道可以通过以下方式对其 Material 3 进行样式设置:

\n

主题.xml

\n
<style name="Theme.Material3.Preference" parent="Theme.Material3.DayNight.NoActionBar">\n    <item name="preferenceTheme">@style/MaterialPreferenceThemeOverlay</item>\n</style>\n\n<style name="MaterialPreferenceThemeOverlay" parent="PreferenceThemeOverlay">\n    <item name="switchPreferenceCompatStyle">@style/Preference.SwitchPreferenceCompat</item>\n</style>\n\n<style name="Preference.SwitchPreferenceCompat" parent="Preference.SwitchPreferenceCompat.Material">\n    <item name="android:widgetLayout">@layout/preference_widget_material_switch</item>\n</style>\n
Run Code Online (Sandbox Code Playgroud)\n

首选项_widget_material_switch.xml

\n
<?xml version="1.0" encoding="utf-8"?>\n<com.google.android.material.materialswitch.MaterialSwitch\n    xmlns:android="http://schemas.android.com/apk/res/android"\n    android:id="@+id/switchWidget"\n    android:layout_width="wrap_content"\n    android:layout_height="wrap_content"\n    android:focusable="false"\n    android:clickable="false"\n    android:background="@null"/>\n
Run Code Online (Sandbox Code Playgroud)\n

设置.xml

\n
<?xml version="1.0" encoding="utf-8"?>\n<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">\n    <SwitchPreferenceCompat\n        android:defaultValue="true"\n        android:key="pref_key"\n        android:summary="Preference Summary"\n        android:title="Preference Title" />\n</PreferenceScreen>\n
Run Code Online (Sandbox Code Playgroud)\n

在此输入图像描述
\n但由于某种原因,我必须像这样以编程方式构建 PreferenceFragment:

\n
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {\n\xc2\xa0 \xc2\xa0 val context = preferenceManager.context\n\xc2\xa0 \xc2\xa0 val screen = preferenceManager.createPreferenceScreen(context)\n\xc2\xa0 \xc2\xa0 val notificationPreference = SwitchPreferenceCompat(context).apply {\n        key = "pref_key"\n        title = "Preference Title"\n        summary="Preference Summary"\n    }\n\xc2\xa0 \xc2\xa0 screen.addPreference(notificationPreference)\n\xc2\xa0 \xc2\xa0 preferenceScreen = screen\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这时候即使我有上面的ThemeOverlay,切换的样式还是老的。\n在此输入图像描述
\n那么,如何以编程方式使用 PreferenceFragmentCompat 中的材质 3 Switch 呢?

\n

我猜想可能可以通过 SwitchPreferenceCompat 的构造函数之一设置主题,但我不了解视图,所以你们能帮助我吗?

\n
SwitchPreferenceCompat(@NonNull Context context)  \n\nSwitchPreferenceCompat(\n    @NonNull Context context,\n    @Nullable AttributeSet attrs\n)  \n\nSwitchPreferenceCompat(\n    @NonNull Context context,\n    @Nullable AttributeSet attrs,\n    int defStyleAttr\n)  \n\nSwitchPreferenceCompat(\n    @NonNull Context context,\n    @Nullable AttributeSet attrs,\n    int defStyleAttr,\n    int defStyleRes\n)\n
Run Code Online (Sandbox Code Playgroud)\n

Sha*_*yro 1

在将您添加SwitchPreference到首选项屏幕之前,您可以使用setWidgetLayout()您传递布局resId的位置preference_widget_material_switch.xml

或者,如果它不起作用(就像在我的项目中),您可以创建一个扩展的自定义视图SwitchPreferenceCompat,并在其 init 块中设置要使用的开关小部件的布局资源 id。

class MaterialSwitchPreference(context: Context): SwitchPreferenceCompat(context) {

    init {
        widgetLayoutResource = R.layout.preference_widget_material_switch
    }

}
Run Code Online (Sandbox Code Playgroud)

然后就用它MaterialSwitchPreference来代替通常的SwitchPrefernce.

注意:我是初学者,我不知道为这样的小事情扩展视图是否是一个很好的做法,但它对我来说效果很好......