在 PreferenceFragmentCompat 中为 PreferenceCategory 设置标题样式

Set Title style for PreferenceCategory in PreferenceFragmentCompat

我想为我的偏好片段屏幕V14设置标题样式。
这就是我想要的:

我已关注
Custom PreferenceCategory Headings
我确实设法获得了相同的屏幕,但使用了 PreferenceFragment!!
我该如何为 PreferenceFragmentCompat V14 做到这一点?


这是我的代码

Style.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="android:listSeparatorTextViewStyle">@style/PreferenceStyle</item>
    <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>

<style name="PreferenceStyle" parent="@android:style/Widget.TextView">
    <item name="android:textColor">@color/colorDialogPop</item>
    <item name="android:textStyle">bold</item>
    <item name="android:textSize">@dimen/text_medium</item>
    <item name="android:padding">@dimen/padding_large</item>
    <item name="android:layout_marginLeft">@dimen/margin_medium</item>
    <item name="android:background">@color/colorAccent</item>
</style>


preference.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

<PreferenceCategory android:title="@string/heading_general"
    android:layout="@layout/settings_text">

    <SwitchPreference
        android:padding="@dimen/padding_medium"
        android:title="@string/enable_push" />

    <SwitchPreference
        android:padding="@dimen/padding_medium"
        android:title="@string/send_email" />

</PreferenceCategory>

<PreferenceCategory android:title="@string/heading_account"
    android:layout="@layout/settings_text">

    <EditTextPreference
        android:padding="@dimen/padding_medium"
        android:title="@string/email" />

    <EditTextPreference
        android:padding="@dimen/padding_medium"
        android:title="@string/name" />

</PreferenceCategory>
</PreferenceScreen>

setting_text.xml 用于标题文本的布局

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@android:id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/PreferenceStyle"
>

</TextView>

我得到的是这个:

Material风格PreferenceCategory不使用android:listSeparatorTextViewStyle。您可以用不同的布局替换所有 PreferenceCategory 和您想要的样式,而不是试图弄乱系统样式。

res/layout/custom_preference_category.xml中:

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/title"
    style="@style/CustomPreferenceCategoryText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="@dimen/margin_medium" />

res/values/styles.xml中:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="preferenceTheme">@style/PreferenceStyle</item>
</style>

<style name="PreferenceStyle" parent="@style/PreferenceThemeOverlay.v14.Material">
    <item name="preferenceCategoryStyle">@style/CustomPreferenceCategory</item>
</style>

<style name="CustomPreferenceCategory" parent="@style/Preference.Category">
    <item name="android:layout">@layout/custom_preference_category</item>
</style>

<style name="CustomPreferenceCategoryText" parent="@android:style/Widget.TextView">
    <!-- Style your PreferenceCategory here. -->
    <item name="android:textColor">@color/colorDialogPop</item>
    <item name="android:textStyle">bold</item>
    <item name="android:textSize">@dimen/text_medium</item>
    <item name="android:padding">@dimen/padding_large</item>
    <item name="android:background">@color/colorAccent</item>
</style>

已解决
我在文本视图周围添加了线性布局,背景以我选择的颜色显示。
这是代码。

settings_text.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<TextView
    android:id="@android:id/title"
    style="@style/CustomPreferenceCategoryText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
</LinearLayout>


style.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="preferenceTheme">@style/PreferenceStyle</item>
</style>

<style name="PreferenceStyle" parent="@style/PreferenceThemeOverlay.v14.Material">
    <item name="preferenceCategoryStyle">@style/CustomPreferenceCategory</item>
</style>

<style name="CustomPreferenceCategory" parent="@style/Preference.Category">
    <item name="android:layout">@layout/settings_text</item>
</style>

<style name="CustomPreferenceCategoryText" parent="@android:style/Widget.TextView">
    <item name="android:textColor">@color/colorDialogPop</item>
    <item name="android:textStyle">bold</item>
    <item name="android:textSize">@dimen/text_medium</item>
    <item name="android:padding">@dimen/padding_large</item>
    <item name="android:background">@color/colorAccent</item>
</style>


preference.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

<PreferenceCategory android:title="@string/heading_general">

    <SwitchPreference
        android:padding="@dimen/padding_medium"
        android:title="@string/enable_push" />

    <SwitchPreference
        android:padding="@dimen/padding_medium"
        android:title="@string/send_weekly_email" />

</PreferenceCategory>

<PreferenceCategory android:title="@string/heading_account">

    <EditTextPreference
        android:padding="@dimen/padding_medium"
        android:title="@string/email" />

    <EditTextPreference
        android:padding="@dimen/padding_medium"
        android:title="@string/name" />

</PreferenceCategory>
</PreferenceScreen>

一个更简单的解决方案是使用 android:layout。 只需在 TextView 上使用 @android:id/title 来设置标题并添加您可能想要使用的任何样式。 这避免了处理主题和样式。

<PreferenceCategory
    android:title="@string/your_general_title"
    android:layout="@layout/your_layout_for_categories"
    >
    :
</PreferenceCategory

文件your_layout_for_categories.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout    
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    >
    <!-- Just to put a simple line above -->
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@color/itemInactive"
        app:layout_constraintBottom_toTopOf="@android:id/title"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        />
    <TextView
        android:id="@android:id/title"
        android:paddingTop="8dp"
        android:paddingLeft="8dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAllCaps="false"
        android:textSize="16sp"
        android:textStyle="bold"
        android:textColor="@color/your_own_color"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        />
        <!-- or instead of using textColor use your own style -->
</androidx.constraintlayout.widget.ConstraintLayout>

这个就简单多了。当然,您应该为所有类别指定 android:layout - 这让您可以更好地控制您想要的内容,并且允许您定义不同的布局(如果您使用上面描述的样式,您最终将定义多个 styles/themes 每个类别)。 如果您的类别应显示图标,请使用 ID @android:id/icon。对于摘要,请使用 @android:id/summary.

最后,如果您想使用自定义小部件设置首选项,请使用 android:widgetLayout。 如果您想以不同的方式呈现首选项,请注意,只有当您定义了 ID 为 @android:id/widget_frame 的容器时,才会设置小部件(例如 SwitchPreference)。通过这种方式,您实际上可以将所有首选项 UI 组件布置在任何您想要的位置。

这是我在 Kotlin 中的做法:

class TemporyPreference @JvmOverloads constructor(
  context: Context,
  attributeSet: AttributeSet? = null,
  defStyleAttr: Int = R.attr.preferenceStyle,
  defStyleRes: Int = 0
) : Preference(context, attributeSet, defStyleAttr, defStyleRes) {
  override fun onBindViewHolder(holder: PreferenceViewHolder?) {
    super.onBindViewHolder(holder)
    holder?.let {
      val textViewTitle = it.findViewById(android.R.id.title) as TextView
      val textViewSummary = it.findViewById(android.R.id.summary) as TextView
      textViewTitle.typeface = ResourcesCompat.getFont(context, R.font.poppins_medium)
      textViewSummary.typeface = ResourcesCompat.getFont(context, R.font.poppins_medium)
    }
  }
}
class TemporyPreferenceCategory @JvmOverloads constructor(
  context: Context,
  attributeSet: AttributeSet? = null,
  defStyleAttr: Int = R.attr.preferenceCategoryStyle,
  defStyleRes: Int = 0
) : PreferenceCategory(context, attributeSet, defStyleAttr, defStyleRes) {
  override fun onBindViewHolder(holder: PreferenceViewHolder?) {
    super.onBindViewHolder(holder)
    holder?.let {
      val textViewTitle = it.findViewById(android.R.id.title) as TextView
      textViewTitle.typeface = ResourcesCompat.getFont(context, R.font.poppins_semibold)
    }
  }
}
<PreferenceScreen>
    <com.planner.planner.ui.settings.preference.TemporyPreferenceCategory
        app:key="other_category"
        app:title="Other">

        <com.planner.planner.ui.settings.preference.TemporyPreference
            app:fragment="com.andreramon.planner.view.settings.imprint.ImprintContentFragment"
            app:key="imprint"
            app:title="@string/settings_category_about_imprint" />

        <com.planner.planner.ui.settings.preference.TemporyPreference
            app:key="@string/settings_feedback"
            app:summary="@string/settings_feedback_summary"
            app:title="@string/settings_feedback" />

    </com.planner.planner.ui.settings.preference.TemporyPreferenceCategory>
</PreferenceScreen>