1

How to change text and background color in a PreferenceScreen inflated by PreferenceFragmentCompat?

Tried How to change the text color of PreferenceCategory/PreferenceScreen but the solution works in a Preference Activity and not in PreferenceFragmentCompat.

Also tried using the layout tag in the preference screen as per How to change text color of preference category in Android? but doesn't save preference.

class FragmentSettings: PreferenceFragmentCompat() {

    private lateinit var viewModel: SharedViewModel

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        addPreferencesFromResource(R.xml.root_preferences)

        val application = requireNotNull(this.activity).application
        val dataBase = DataBase.getInstance(application)
        val repo = Repo(dataBase!!)

        viewModel = ViewModelProvider(this,
            SharedViewModelFactory(
                dataBase
            )
        ).get(SharedViewModel::class.java)

        (activity as MainActivity).supportActionBar?.title = "Settings"
}
            

This is the code in my settingsPreference.xml.

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@color/colorExtra"
    android:backgroundTint="@color/colorExtra">

    <PreferenceCategory android:layout="@layout/pref_title" app:title="@string/location_header">

        <SwitchPreferenceCompat
            android:background="@color/colorExtra"
            android:backgroundTint="@color/colorExtra"
            app:defaultValue="true"
            android:layout= "@layout/switch_pref_item"
            app:disableDependentsState="true"
            app:key="USE_DEVICE_LOCATION"
            app:summary="Allow the app to get your location"
            app:title="@string/your_location_title" />

        <EditTextPreference
            android:background="@color/colorExtra"
            android:backgroundTint="@color/colorExtra"
            app:dependency="USE_DEVICE_LOCATION"
            app:key="setLocation"
            android:layout="@layout/set_location_pref"
            app:title="@string/set_location_title"
            app:useSimpleSummaryProvider="true" />


    </PreferenceCategory>

</PreferenceScreen>
James Z
  • 12,209
  • 10
  • 24
  • 44
Andrew Chelix
  • 1,012
  • 11
  • 16

1 Answers1

1

This should be done via styles, and follows the same procedure used to style any layout. It is not done via the preferences xml.

Make an xml style that is a child of Theme.AppCompat. Then you can override the colors for android:windowBackground and android:textColor. You can apply this style to the activity in the manifest.

For example, in styles.xml:

<color name="preferencesTextColor">$ff0000</color>
<color name="preferencesBackgroundColor">#202020</color>

<style name="MyPreferencesTheme" parent="Theme.AppCompat">
    <item name="android:textColor">@color/preferencesTextColor</item>
    <item name="android:windowBackground">@color/preferencesBackgroundColor</item>
</style>

Then in the manifest, apply the theme to the activity:

<activity android:name="MyPreferencesActivity"
    android:theme="@style/MyPreferencesTheme"
    android:label="@string/myPreferenceActivityLabel" />
Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • If you put it in the MainActivity will it work in the PreferenceFragmentCompat? Also does it mean that it will affect other fragments and layouts eg. if i set the text color to blue in the activity theme, will the text color be blue in other layouts? – Andrew Chelix Jul 20 '20 at 10:07
  • Can this approach be used if you want to set the theme based on the user preference e.g Can you set the theme to be bright for light mode and dark for night mode based on the user? – Andrew Chelix Jul 20 '20 at 11:07
  • The theme applies to the whole activity. If you want to apply it to a specific preference fragment, I don't know if they've provided a clean way to do it. With typical views and fragments, you can add a style in their layout element in the layout xml, but PreferenceFragmentCompat doesn't go into xml layouts. I always host it in its own Activity. – Tenfour04 Jul 20 '20 at 13:31
  • A number of features in the preference library rely on the Activity implementing certain interfaces, so I don't think they have designed it to work well with a single-Activity architecture. So I end up using one activity for everything except the settings screen, and then one activity just for the settings. – Tenfour04 Jul 20 '20 at 13:31
  • You can inherit from `Theme.AppCompat.DayNight` to create a theme that will respond to the user's dark mode settings. – Tenfour04 Jul 20 '20 at 13:33
  • Do not forget, to add this element for value text color : '''@color/preferencesTextColor ''' – Sofien Rahmouni Oct 18 '22 at 07:55