Set Title style for PreferenceCategory in PreferenceFragmentCompat

11,350

Solution 1

SOLVED
I added the Linear Layout around the Text View and the background gets visible in my choice of color.
Here is the code.

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>

Solution 2

Material style PreferenceCategory does not use android:listSeparatorTextViewStyle. Instead of trying to mess with the system styles, you can substitute a different layout for all your PreferenceCategorys and style that however you want.

In 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" />

In 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>

Solution 3

A far simpler solution is to use android:layout. Just use @android:id/title on the TextView to set the title and add any styles you may want to use. This avoids having to deal with themes and styles.

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

File 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>

This is much simpler. Of course, you should specify android:layout to all categories - this gives you more control on what exactly you want, plus allows you to define different layouts (if you use styles as depicted above, you will end up defining several styles/themes for each category). If your category should display an icon, use ID @android:id/icon. For summary, use @android:id/summary.

Finally, if you want to set a preference with a custom widget, use android:widgetLayout. If you want to render a preference in a different way, note that the widget (say, SwitchPreference) will set only and only if you have defined a container with ID @android:id/widget_frame. In this way, you can actually layout all the preference UI components anywhere you want.

Solution 4

This is how I did it in 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>
Share:
11,350
Abhinav Tyagi
Author by

Abhinav Tyagi

Just say "Ok Google, Talk to Innovative Solitaire" to your Google Assistant to know more about me professionally. Link to my virtual assistant: Innovative Solitaire

Updated on June 04, 2022

Comments

  • Abhinav Tyagi
    Abhinav Tyagi about 2 years

    I want to set title style for my preference fragment screen V14.
    This is what I want:
    enter image description here

    I have followed
    Custom PreferenceCategory Headings
    I did manage to get the same screen but with PreferenceFragment!!
    How can I do it for PreferenceFragmentCompat V14??


    Here is my Code

    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 for layout of title text

    <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>
    

    All I get is this:
    enter image description here

  • Abhinav Tyagi
    Abhinav Tyagi almost 8 years
    What is @style/PreferenceCategory? It is not defined above!
  • Abhinav Tyagi
    Abhinav Tyagi almost 8 years
    Not working !! I have put what you suggested with <style name="PreferenceStyle" parent="@style/PreferenceThemeOverlay.v14.Material"> <item name="preferenceCategoryStyle">@style/Preference.Category</i‌​tem> </style>
  • Abhinav Tyagi
    Abhinav Tyagi almost 8 years
    can you edit your code and put the correction? <item name="preferenceCategoryStyle">@style/PreferenceCategory</it‌​em> is giving me error!!
  • Karakuri
    Karakuri almost 8 years
    This is exactly the solution that I gave you but with a different layout :/
  • Karakuri
    Karakuri almost 8 years
    no, the issue was the typo that I fixed in my answer
  • anoo_radha
    anoo_radha about 6 years
    Works fine now!