Building an Android Settings Screen (Part 1)

How to Create and Theme the Overview Screen

Jakob Ulbrich
4 min readMay 28, 2016
Fixing and Extending the android.support.v7.preference Library

Some days ago, I started building a Setting Screen for my Android app. Everything was fine, until I opened it on an older Android version. The overview screen had no material design, a thing I would have accepted, if there weren’t those completely destroyed dialogs: Android’s internal preferences are using Android’s internal app.AlertDialogs. Those dialogs in combination with the AppCompat Dialog Theme, which I had applied to them, resulted in a dialog with two frames on older devices (One system default dialog and a material frame around it).
So I decided to switch to the android.support.v7.preference library, only to face a lot more issues.

This tutorial series should help you, to fix the numerous design issues in the v7.preference library and to build custom preferences.

This part of the tutorial was updated to use the latest version (v28.0.0) of the support library. It still contains the information on how to fix issues with some older versions.

Including the Library

In order to use the new preferences, we need to import a library. To do so, we add this line to our gradle dependencies.

implementation 'com.android.support:preference-v7:28.0.0'

Building The Preference Screen

Creating the Preferences

At first, we need to create our preference structure: We create a new XML Android resource file as xml/app_preferences.xml. Now we can add our preference structure to this file. Make sure to add a unique android:key attribute for each preference. More information: How to build the XML

<android.support.v7.preference.PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">

<android.support.v7.preference.PreferenceCategory
android:title="Category 1">

<android.support.v7.preference.SwitchPreferenceCompat
android:key="key1"
android:title="Switch Preference"
android:summary="Switch Summary"
android:defaultValue="true" />

<android.support.v7.preference.EditTextPreference
android:key="key2"
android:title="EditText Preference"
android:summary="EditText Summary"
android:dialogMessage="Dialog Message"
android:defaultValue="Default value" />
<android.support.v7.preference.CheckBoxPreference
android:key="key3"
android:title="CheckBox Preference"
android:summary="CheckBox Summary"
android:defaultValue="true"/>
</android.support.v7.preference.PreferenceCategory>

</android.support.v7.preference.PreferenceScreen>

The v7.preference library provides some preferences we can use: CheckBoxPreference, SwitchPreferenceCompat, EditTextPreference and a ListPreference (and a basic Preference). If we need more than these predefined preferences, we have to build them on our own.

Creating the Preference Fragment

Now we need to create our Preference Fragment, where we can show the preferences from our XML file. We do this by creating a new class, called SettingsFragment, which extends PreferenceFragmentCompat. Since the onCreatePreferences is declared as abstract in the source code of the library, we are forced to include our own implementation to tell the fragment to load our just created app_preferences.xml.

import android.support.v7.preference.PreferenceFragmentCompat;class SettingsFragment: PreferenceFragmentCompat() {    override fun onCreatePreferences(bundle: Bundle?, s: String?) {
// Load the Preferences from the XML file
addPreferencesFromResource(R.xml.app_preferences);
}
}

We can add this SettingsFragment (v4.app.Fragment), like any other Fragment (e.g. with a FragmentTransaction) to an Activity.

Applying the Preference Theme

If you are using newer versions of the support library, the preferences are automatically using the material design PreferenceThemeOverlay from the v7.preference library.

Settings Screen with PreferenceThemeOverlay

The result should look like this. In this example the Activity’s parent theme is Theme.AppCompat and the background is set with android:windowBackground. We can change the color of the CheckBox, the Switch and the PreferenceCategory title by changing the colorAccent in our Activity’s theme. If you specifically want to customize the theme of the preferences, you can do so by overriding the following attribute in your Activity’s theme and extending the predefined ThemeOverlay:

<style name="Theme.App" parent="Theme.AppCompat">
<item name="preferenceTheme">@style/Theme.App.Preferences</item>
</style>
<style name="Theme.App.Preferences" parent="PreferenceThemeOverlay">
...
</style>

Using Older Versions of the Support Library

If you are using an older version of the support library (e.g. 23.4.0) and are unable to update to the latest one for some reason, you might experience some additional problems.

The App might crash with an IllegalStateException if you do not specify the preferenceTheme attribute in you Activity’s theme. To resolve this issue, just add it as mentioned above.

Settings Screen with PreferenceThemeOverlay

You might also experience some design issues similar to the following. As you can see, it has an oversized font and a horizontal line below the category title. This is definitely not following the material design guidelines. It more looks like a mixture of material design for the CheckBox and Switch widgets on the right and an old design for everything else.

This happens because older versions of the support library do not directly include the necessary material themes. They are included in the v14.preference library. It is an addition to the v7.preference library that requires a higher minimum SDK version. This means for us, that we have to add one more line to our dependencies.

implementation 'com.android.support:preference-v14:23.4.0'

Now we have access to two more themes: PreferenceThemeOverlay.v14 and PreferenceThemeOverlay.v14.Material. To use the material theme, we simply change the preferenceTheme in our Activity’s theme.

<item name="preferenceTheme">
@style/PreferenceThemeOverlay.v14.Material
</item>

After applying this, the font should not be oversized anymore and also the horizontal line below the category title should have disappeared.

A side effect of including the v14.preference library is that we can use a new preference called MultiSelectListPreference (it requires the v7.preference library to work).

This was only the first step to create a material design Settings Screen. As soon as you open the Alert Dialog of the EditText preference, you will find more design issues. The next parts of this tutorial will include how to solve the design issues and how to build custom preferences.

The second Part of this tutorial series is available below.

You can have a look at the project files on GitHub.

Thanks for reading and happy coding 💻.

--

--