8

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

Community
  • 1
  • 1
Abhinav Tyagi
  • 5,158
  • 3
  • 30
  • 60
  • Shouldn't the file name be `preference_category.xml` and not `setting_text.xml`? – Sharjeel Jul 09 '16 at 07:41
  • That is the name of layout file that I have created form custom title. – Abhinav Tyagi Jul 09 '16 at 07:45
  • 1
    You created a custom layout `setting_text.xml` but where do you set it as default layout? The example you referred to made a copy of system layout `preference_category.xml` file in the application with the same name that's why didn't set it again. The answer below is a better approach where you created your custom layout and set it using style. – Sharjeel Jul 09 '16 at 10:22
  • 1
    I set it in preference.xml file – Abhinav Tyagi Jul 09 '16 at 10:28
  • below code is either incomplete or missing some code! it is giving me same error result – Abhinav Tyagi Jul 09 '16 at 10:31
  • I agree with Abhinav, setting the layout in the xml file is the way to go! android:layout="@layout/pref_cat_line" and in pref_cat_line, – pstorli Jun 25 '18 at 17:33

4 Answers4

19

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>
Karakuri
  • 38,365
  • 12
  • 84
  • 104
7

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.

miguelt
  • 384
  • 4
  • 8
5

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>
Abhinav Tyagi
  • 5,158
  • 3
  • 30
  • 60
1

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>
Andre Thiele
  • 3,202
  • 3
  • 20
  • 43