Skip to content

Settings with PreferenceFragment

Jay Tolentino edited this page Jan 12, 2015 · 18 revisions

Overview

In Android apps, there are often settings pages that contain different options the user can tweak. The PreferenceFragment contains a hierarchy of preference objects displayed on screen in a list. These preferences will automatically save to SharedPreferences as the user interacts with them.

Defining the XML

First, define the preference object hierarchy by creating a new xml file in res/xml:

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

    <CheckBoxPreference
        android:key="checkbox_preference"
        android:title="@string/title_checkbox_preference"
        android:defaultValue="@string/default_checkbox_preference"/>
    
    <EditTextPreference
        android:key="edittext_preference"
        android:title="@string/title_edittext_preference"
        android:summary="@string/summary_edittext_preference"
        android:dialogTitle="@string/dialog_title_edittext_preference" />
        
</PreferenceScreen>

All preferences are saved as key-value pairs in the default SharedPreferences with the key specified through the xml above. To retrieve an instance of those preferences, call the following with a context in the same package as the fragment:

SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(android.content.Context);

The root for the XML file must be a <PreferenceScreen. Within this screen, you can either list all preferences or group with <PreferenceCategory>. The grouped preferences will appear together under the same section heading:

Settings Screen

To see the xml that created the above settings, refer to this gist.

Preference Types

There are several main types of preferences used for settings. Two of these types (ListPreference and EditTextPreference) descend from DialogPreference and can therefore define dialog-specific attributes in the XML (e.g. a dialogTitle). All preferences may persist boolean, string, long, or integer values to the SharedPreferences file.

This preference opens a dialog with a list of options for the user to choose. It persists a string value. The array of human-readable options displayed to the user are specified using android:entries. The values of each corresponding option are defined by android:entryValues.

    <ListPreference
        android:key="list_preference"
        android:title="@string/title_list_preference"
        android:dialogTitle="@string/dialog_title_list_preference"
        android:entries="@array/entries_list_preference"
        android:entryValues="@array/entryvalues_list_preference" />

This preference opens a dialog with an EditText view that can capture user typed input. It persists a string value.

     <EditTextPreference
        android:key="edittext_preference"
        android:title="@string/title_edittext_preference"
        android:dialogTitle="@string/dialog_title_edit_text_preference" />

This preference displays a checkbox, using the checkbox's state to persist a boolean (true for checked, false for unchecked).

    <CheckBoxPreference
        android:key="checkbox_preference"
        android:title="@string/title_checkbox_preference"
        android:defaultValue="@string/default_checkbox_preference"/>

This preference displays a switch, using the switch's state to persist a boolean (true when switched on, false when switched off). This preference type was introduced in API 14 as a subclass of TwoStatePreference. CheckBoxPreference was then also implemented to also be a direct subclass of it rather directly fromPreference.

To use it, your app needs to use either min API level 14 or the Android support v4 library.

<SwitchPreference
    android:key="switch_preference"
    android:title="@string/title_switch_preference"
    android:defaultValue="true" />
Intents

Preferences can also hold intents which, when clicked, can open a new activity or perform other intent actions. No data is persisted.

    <Preference
        android:title="@string/title_intent_preference">
        <intent android:action="android.intent.action.VIEW"
            android:data="http://codepath.com/" />
    </Preference>

Java Implementation

Use PreferenceFragment to programatically handle preferences. To load the settings into the fragment, load the preferences in the onCreate() method. To get an instance of a preference, search for a preference using its key through the PreferenceManager within onCreateView(). You can use this instance to customize the preference, such as add a custom OnPreferenceChangeListener.

public class SettingsFragment extends PreferenceFragment {
    
    private ListPreference mListPreference;
    
    ...
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.settings);
    }
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        
        mListPreference = (ListPreference)  getPreferenceManager().findPreference("preference_key");
        mListPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
            @Override
            public boolean onPreferenceChange(Preference preference, Object newValue) {
                // insert custom code
            }
        }
        
        return inflater.inflate(R.layout.fragment_settings, container, false);
    }
}

Currently, Android support v4 does not support PreferenceFragment. For alternatives, there are several open-source projects available:

You can also follow this issue on the Android issue tracker.

Custom Preferences

If none of the previous preference types work for your needs, you can create a custom preference extending from DialogPreference, TwoStatePreference, or Preference itself.

(..in progress...)

For a detailed guide on implementing a custom preference, refer to the Android Developer: Settings API guide.

References

Finding these guides helpful?

We need help from the broader community to improve these guides, add new topics and keep the topics up-to-date. See our contribution guidelines here and our topic issues list for great ways to help out.

Check these same guides through our standalone viewer for a better browsing experience and an improved search. Follow us on twitter @codepath for access to more useful Android development resources.

Clone this wiki locally