Skip to content
This repository has been archived by the owner on Mar 3, 2023. It is now read-only.

Android Settings Screen

Miroslav Smukov edited this page Sep 3, 2016 · 10 revisions

Settings Screen

The UI of our application is almost done, just a couple more screens to go. It is the perfect time to implement the Settings screen where we'll allow our users to setup the app according to their own preferences.

We won't have a lot of settings at this time, the list will probably grow as we continue the app development, but it is always important to make the first steps. In this page we'll add three different checkbox options:

  • Make me discoverable by others
  • Notifications for Messages
  • Notifications for Invites

We'll also set the default values for those options and make them apply once the app is run for the first time.

Google Recommends

When I started working on this feature in my Android app, I did a quick google search and found this official google documentation. Apparently, there's already a supper easy way to implement the full Settings feature in native Android, including saving & loading of the settings and supporting multiple levels of settings (master-detail). For a full guide checkout this link. I'll also try to take out the most important bits that I applied in my project.

Overview

Instead of using View objects to build the user interface, settings are built using various subclasses of the Preference class that you declare in an XML file.

A Preference object is the building block for a single setting. Each Preference appears as an item in a list and provides the appropriate UI for users to modify the setting. For example, a CheckBoxPreference creates a list item that shows a checkbox, and a ListPreference creates an item that opens a dialog with a list of choices.

Each Preference you add has a corresponding key-value pair that the system uses to save the setting in a default SharedPreferences file for your app's settings. When the user changes a setting, the system updates the corresponding value in the SharedPreferences file for you. The only time you should directly interact with the associated SharedPreferences file is when you need to read the value in order to determine your app's behavior based on the user's setting.

The value saved in SharedPreferences for each setting can be one of the following data types:

  • Boolean
  • Float
  • Int
  • Long
  • String
  • String Set

A list of available Preference subclasses that can be used:

  • CheckBoxPreference - This preference will store a boolean into the SharedPreferences.
  • EditTextPreference - It is a subclass of DialogPreference and shows the EditText in a dialog. The saved value is a string.
  • ListPreference -A Preference that displays a list of entries as a dialog. This preference will store a string into the SharedPreferences.
  • MultiSelectListPreference - A Preference that displays a list of entries as a dialog. This preference will store a set of strings into the SharedPreferences.
  • SwitchPreference - A Preference that provides a two-state toggleable option. This preference will store a boolean into the SharedPreferences.
  • PreferenceCategory - Used to group Preference objects and provide a disabled title above the group.

Defining Preferences in XML

Each Preference subclass above can be declared with an XML element that matches the class name, such as <CheckBoxPreference>.

You must save the XML file in the res/xml/ directory. Although you can name the file anything you want, it's traditionally named preferences.xml. You usually need only one file, because branches in the hierarchy (that open their own list of settings) are declared using nested instances of PreferenceScreen. However, if you want to create a multi-pane layout for your settings, then you need separate XML files for each fragment.

The root node for the XML file must be a element. Within this element is where you add each Preference. Each child you add within the <PreferenceScreen> element appears as a single item in the list of settings.

Below you can see a sample of my preferences.xml page that I used in my project: Source Code

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <SwitchPreference
        android:key="pref_discoverable"
        android:title="@string/pref_discoverable"
        android:defaultValue="true" />
    <SwitchPreference
        android:key="pref_notification_messages"
        android:title="@string/pref_notify_messages"
        android:defaultValue="true" />
    <SwitchPreference
        android:key="pref_notification_invites"
        android:title="@string/pref_notify_invites"
        android:defaultValue="true" />
</PreferenceScreen>

All items include at least these three attributes:

  • android:key - This attribute is required for preferences that persist a data value. It specifies the unique key (a string) the system uses when saving this setting's value in the SharedPreferences.
  • android:title - This provides a user-visible name for the setting.
  • android:defaultValue - This specifies the initial value that the system should set in the SharedPreferences file. You should supply a default value for all settings.

Preference Fragment

To implement the Settings (Preferences) screen you can use PreferenceActivity, or the PreferenceFragment. Google recommends using a Fragment instead of the full Activity, so that's what we'll use as well.

The full implementation of the fragment can be as simple as the code below, however, follow the source code link to see additional code specific to this project:

Source Code

public class SettingsFragment extends PreferenceFragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Load the preferences from an XML resource
        addPreferencesFromResource(R.xml.preferences);
    }
}

Setting Default Values

You can easily initialize the associated SharedPreferences file with default values for each Preference when the user first opens your application.

The first thing you must do is specify a default value for each Preference object in your XML file using the android:defaultValue attribute. The value can be any data type that is appropriate for the corresponding Preference object.

Then, from the onCreate() method in your application's main activity — and in any other activity through which the user may enter your application for the first time — call setDefaultValues() (we did this in our NavigationActivity class):

PreferenceManager.setDefaultValues(this, R.xml.preferences, false);

Calling this during onCreate() ensures that your application is properly initialized with default settings, which your application might need to read in order to determine some behaviors (such as whether to download data while on a cellular network).

This method takes three arguments:

  • Your application Context.
  • The resource ID for the preference XML file for which you want to set the default values.
  • A boolean indicating whether the default values should be set more than once. When false, the system sets the default values only if this method has never been called in the past. This makes it safe to call this method every time your activity starts without overriding the user's saved preferences by resetting them to the defaults.

Reading Preferences

By default, all your app's preferences are saved to a file that's accessible from anywhere within your application by calling the static method PreferenceManager.getDefaultSharedPreferences(). This returns the SharedPreferences object containing all the key-value pairs that are associated with the Preference objects used in your PreferenceActivity or PreferenceFragment.

For example, here's how you can read one of the preference values from any other activity in your application:

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String syncConnPref = sharedPref.getString(SettingsActivity.KEY_PREF_SYNC_CONN, "");

Conclusion

Did I just implemented the full Settings page in 5 minutes?

Android Settings Screen

References

Commits

Clone this wiki locally