Logo Icon Logo
A Crowd-sourced Cookbook on Writing Great Android® Apps
GitHub logo Twitter logo OReilly Book Cover Art

Providing User Preference Activity with Minimal Effort

Author: Ian Darwin
Published? true -- FormatLanguage: W

Problem:

You want to let the user specify one or more preferences values, and have them persisted across runs of the program.

Solution:

Have your Preferences or Settings menuitem or button load an Activity that subclasses PreferenceActivity; in its onCreate(), load the XML PreferenceScreen.

Discussion:

Android will happily maintain a SharedPreferences object for you in semi-permanent storage. To retrieve settings from it, use

sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);

This should be called in your main activity's onCreate() method, or in the onCreate() of any Activity that needs to view the user's chosen preferences.

You do need to tell Android what values you want the user to be able to specify, such as Name, Twitter Account, Favorite Color, or whatever. You don't use the traditional View items such as ListView or Spinner, but instead use the special Preference items. There is a reasonable set of choices available, such as Lists, Text, CheckBoxes, etc. Example xx-1 uses a List, a TextEdit and a Checkbox.

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

	<ListPreference
		android:key="listChoice"
		android:title="List Choice"
		android:entries="@array/choices"
		android:entryValues="@array/choices"
		/>

	<PreferenceCategory 
		android:title="Personal">
		
		<EditTextPreference
			android:key="nameChoice"
			android:title="Name"
			android:hint="Name"
		/>
			
		<CheckBoxPreference
			android:key="booleanChoice"
			android:title="Binary Choice"
		/>
			
	</PreferenceCategory>
	
</PreferenceScreen>

The PreferenceCategory in the XML allows you to subdivide your panel into labelled sections. It is also possible to have more than one PreferenceScreen if you have a large number of settings and want to divide it into "pages". There are several other kinds of UI element that can be used in the XML PreferencesScreen; see the official documentation for details.

The PreferenceActivity subclass consists of nothing more than this onCreate() method:

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		addPreferencesFromResource(R.layout.prefs);
	}

When activated, the PreferenceActivity looks like Figure XX-1.

When the user clicks on, say, Name, an Edit dialog opens, as in Figure XX-2.

In the XML layout for the Preferences screen, each preference setting is assigned a name or "key", as in a Java Map or Properties. The supported value types are the obvious String, Integer, Float and Boolean. You use this to retrieve the user's values, and you provide a default value in case the settings screen hasn't been put up yet or in case the user didn't bother to specify a particular setting.

String preferredName =
    sharedPreferences.getString("nameChoice", "No name");

Like many Android apps, this demo has no Back button from its Preferences; the user simply presses the system Back button. When they get back to the main activity, in a real app it would operated based on the user's choices. My demo app simply displays the values. This is shown in Figure XX-3.

But basically that's all that's needed: an XML PreferencesScreen to define the properties and how the user sets them, a call to getDefaultSharedPrefences(), and calls to getString(), getBoolean(), etc., on the returned SharedPreferences object. It's easy to do Prefences this way, and it gives the Android system a feel of uniformity and consistency and predictability that is important to the overall User Experience.

mwilhelm 2012-03-24 09:38:31.445 In the above paragraph you say that PreferenceGroup in the XML allows you to subdivide your panels... But in the XML you don't seem to be using that key word, rather PreferenceCategory. Should this be changed or am I missing something.