summaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorScott Main <smain@google.com>2012-03-09 19:10:40 -0800
committerScott Main <smain@google.com>2012-07-25 13:52:46 -0700
commitbbb3f41e26ac5a996913907dc63786146132b4ce (patch)
tree44c3c366cedcebb8702501b6b094672db684153c /docs
parent156671ef9a6581b6790bb17bfda8a9efcf9f0693 (diff)
downloadframeworks_base-bbb3f41e26ac5a996913907dc63786146132b4ce.zip
frameworks_base-bbb3f41e26ac5a996913907dc63786146132b4ce.tar.gz
frameworks_base-bbb3f41e26ac5a996913907dc63786146132b4ce.tar.bz2
docs: add Settings dev guide;
a few changes to javadocs Change-Id: I2d671aafe91e4c6e224e2a556a60dce9f93f11ae
Diffstat (limited to 'docs')
-rw-r--r--docs/html/guide/components/fragments.jd6
-rw-r--r--docs/html/guide/guide_toc.cs3
-rw-r--r--docs/html/guide/topics/ui/settings.jd1171
-rw-r--r--docs/html/images/ui/settings/settings-headers-handset.pngbin0 -> 57277 bytes
-rw-r--r--docs/html/images/ui/settings/settings-headers-tablet.pngbin0 -> 52567 bytes
-rw-r--r--docs/html/images/ui/settings/settings-subscreen.pngbin0 -> 49541 bytes
-rw-r--r--docs/html/images/ui/settings/settings-titles.pngbin0 -> 66806 bytes
-rw-r--r--docs/html/images/ui/settings/settings.pngbin0 -> 96681 bytes
8 files changed, 1180 insertions, 0 deletions
diff --git a/docs/html/guide/components/fragments.jd b/docs/html/guide/components/fragments.jd
index 938e0ab..4f62033 100644
--- a/docs/html/guide/components/fragments.jd
+++ b/docs/html/guide/components/fragments.jd
@@ -709,6 +709,12 @@ href="{@docRoot}guide/components/activities.html#Lifecycle">managing the activit
lifecycle</a> also apply to fragments. What you also need to understand, though, is how the life
of the activity affects the life of the fragment.</p>
+<p class="caution"><strong>Caution:</strong> If you need a {@link android.content.Context} object
+within your {@link android.app.Fragment}, you can call {@link android.app.Fragment#getActivity()}.
+However, be careful to call {@link android.app.Fragment#getActivity()} only when the fragment is
+attached to an activity. When the fragment is not yet attached, or was detached during the end of
+its lifecycle, {@link android.app.Fragment#getActivity()} will return null.</p>
+
<h3 id="CoordinatingWithActivity">Coordinating with the activity lifecycle</h3>
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 94b9773..9465f18 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -197,6 +197,9 @@
<li><a href="<?cs var:toroot ?>guide/topics/ui/actionbar.html">
<span class="en">Action Bar</span>
</a></li>
+ <li><a href="<?cs var:toroot ?>guide/topics/ui/settings.html">
+ <span class="en">Settings</span>
+ </a></li>
<li class="nav-section">
<div class="nav-section-header"><a href="<?cs var:toroot ?>guide/topics/ui/notifiers/index.html">
<span class="en">Notifications</span>
diff --git a/docs/html/guide/topics/ui/settings.jd b/docs/html/guide/topics/ui/settings.jd
new file mode 100644
index 0000000..fd3b684
--- /dev/null
+++ b/docs/html/guide/topics/ui/settings.jd
@@ -0,0 +1,1171 @@
+page.title=Settings
+@jd:body
+
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+<ol>
+ <li><a href="#Overview">Overview</a>
+ <ol>
+ <li><a href="#SettingTypes">Preferences</a></li>
+ </ol>
+ </li>
+ <li><a href="#DefiningPrefs">Defining Preferences in XML</a>
+ <ol>
+ <li><a href="#Groups">Creating setting groups</a></li>
+ <li><a href="#Intents">Using intents</a></li>
+ </ol>
+ </li>
+ <li><a href="#Activity">Creating a Preference Activity</a></li>
+ <li><a href="#Fragment">Using Preference Fragments</a></li>
+ <li><a href="#Defaults">Setting Default Values</a></li>
+ <li><a href="#PreferenceHeaders">Using Preference Headers</a>
+ <ol>
+ <li><a href="#CreateHeaders">Creating the headers file</a></li>
+ <li><a href="#DisplayHeaders">Displaying the headers</a></li>
+ <li><a href="#BackCompatHeaders">Supporting older versions with preference headers</a></li>
+ </ol>
+ </li>
+ <li><a href="#ReadingPrefs">Reading Preferences</a>
+ <ol>
+ <li><a href="#Listening">Listening for preference changes</a></li>
+ </ol>
+ </li>
+ <li><a href="#NetworkUsage">Managing Network Usage</a></li>
+ <li><a href="#Custom">Building a Custom Preference</a>
+ <ol>
+ <li><a href="#CustomSelected">Specifying the user interface</a></li>
+ <li><a href="#CustomSave">Saving the setting's value</a></li>
+ <li><a href="#CustomInitialize">Initializing the current value</a></li>
+ <li><a href="#CustomDefault">Providing a default value</a></li>
+ <li><a href="#CustomSaveState">Saving and restoring the Preference's state</a></li>
+ </ol>
+ </li>
+</ol>
+
+<h2>Key classes</h2>
+<ol>
+ <li>{@link android.preference.Preference}</li>
+ <li>{@link android.preference.PreferenceActivity}</li>
+ <li>{@link android.preference.PreferenceFragment}</li>
+</ol>
+
+
+<h2>See also</h2>
+<ol>
+ <li><a
+href="{@docRoot}design/patterns/settings.html">Settings design guide</a></li>
+</ol>
+</div>
+</div>
+
+
+
+
+<p>Applications often include settings that allow users to modify app features and behaviors. For
+example, some apps allow users to specify whether notifications are enabled or specify how often the
+application syncs data with the cloud.</p>
+
+<p>If you want to provide settings for your app, you should use
+Android's {@link android.preference.Preference} APIs to build an interface that's consistent with
+the user experience in other Android apps (including the system settings). This document describes
+how to build your app settings using {@link android.preference.Preference} APIs.</p>
+
+<div class="note design">
+<p><strong>Settings Design</strong></p>
+ <p>For information about how to design your settings, read the <a
+href="{@docRoot}design/patterns/settings.html">Settings</a> design guide.</p>
+</div>
+
+
+<img src="{@docRoot}images/ui/settings/settings.png" alt="" width="435" />
+<p class="img-caption"><strong>Figure 1.</strong> Screenshots from the Android Messaging app's
+settings. Selecting an item defined by a {@link android.preference.Preference}
+opens an interface to change the setting.</p>
+
+
+
+
+<h2 id="Overview">Overview</h2>
+
+<p>Instead of using {@link android.view.View} objects to build the user interface, settings are
+built using various subclasses of the {@link android.preference.Preference} class that you
+declare in an XML file.</p>
+
+<p>A {@link android.preference.Preference} object is the building block for a single
+setting. Each {@link android.preference.Preference} appears as an item in a list and provides the
+appropriate UI for users to modify the setting. For example, a {@link
+android.preference.CheckBoxPreference} creates a list item that shows a checkbox, and a {@link
+android.preference.ListPreference} creates an item that opens a dialog with a list of choices.</p>
+
+<p>Each {@link android.preference.Preference} you add has a corresponding key-value pair that
+the system uses to save the setting in a default {@link android.content.SharedPreferences}
+file for your app's settings. When the user changes a setting, the system updates the corresponding
+value in the {@link android.content.SharedPreferences} file for you. The only time you should
+directly interact with the associated {@link android.content.SharedPreferences} file is when you
+need to read the value in order to determine your app's behavior based on the user's setting.</p>
+
+<p>The value saved in {@link android.content.SharedPreferences} for each setting can be one of the
+following data types:</p>
+
+<ul>
+ <li>Boolean</li>
+ <li>Float</li>
+ <li>Int</li>
+ <li>Long</li>
+ <li>String</li>
+ <li>String {@link java.util.Set}</li>
+</ul>
+
+<p>Because your app's settings UI is built using {@link android.preference.Preference} objects
+instead of
+{@link android.view.View} objects, you need to use a specialized {@link android.app.Activity} or
+{@link android.app.Fragment} subclass to display the list settings:</p>
+
+<ul>
+ <li>If your app supports versions of Android older than 3.0 (API level 10 and lower), you must
+build the activity as an extension of the {@link android.preference.PreferenceActivity} class.</li>
+ <li>On Android 3.0 and later, you should instead use a traditional {@link android.app.Activity}
+that hosts a {@link android.preference.PreferenceFragment} that displays your app settings.
+However, you can also use {@link android.preference.PreferenceActivity} to create a two-pane layout
+for large screens when you have multiple groups of settings.</li>
+</ul>
+
+<p>How to set up your {@link android.preference.PreferenceActivity} and instances of {@link
+android.preference.PreferenceFragment} is discussed in the sections about <a
+href="#Activity">Creating a Preference Activity</a> and <a href="#Fragment">Using
+Preference Fragments</a>.</p>
+
+
+<h3 id="SettingTypes">Preferences</h3>
+
+<p>Every setting for your app is represented by a specific subclass of the {@link
+android.preference.Preference} class. Each subclass includes a set of core properties that allow you
+to specify things such as a title for the setting and the default value. Each subclass also provides
+its own specialized properties and user interface. For instance, figure 1 shows a screenshot from
+the Messaging app's settings. Each list item in the settings screen is backed by a different {@link
+android.preference.Preference} object.</p>
+
+<p>A few of the most common preferences are:</p>
+
+<dl>
+ <dt>{@link android.preference.CheckBoxPreference}</dt>
+ <dd>Shows an item with a checkbox for a setting that is either enabled or disabled. The saved
+value is a boolean (<code>true</code> if it's checked).</dd>
+
+ <dt>{@link android.preference.ListPreference}</dt>
+ <dd>Opens a dialog with a list of radio buttons. The saved value
+can be any one of the supported value types (listed above).</dd>
+
+ <dt>{@link android.preference.EditTextPreference}</dt>
+ <dd>Opens a dialog with an {@link android.widget.EditText} widget. The saved value is a {@link
+java.lang.String}.</dd>
+</dl>
+
+<p>See the {@link android.preference.Preference} class for a list of all other subclasses and their
+corresponding properties.</p>
+
+<p>Of course, the built-in classes don't accommodate every need and your application might require
+something more specialized. For example, the platform currently does not provide a {@link
+android.preference.Preference} class for picking a number or a date. So you might need to define
+your own {@link android.preference.Preference} subclass. For help doing so, see the section about <a
+href="#Custom">Building a Custom Preference</a>.</p>
+
+
+
+<h2 id="DefiningPrefs">Defining Preferences in XML</h2>
+
+<p>Although you can instantiate new {@link android.preference.Preference} objects at runtime, you
+should define your list of settings in XML with a hierarchy of {@link android.preference.Preference}
+objects. Using an XML file to define your collection of settings is preferred because the file
+provides an easy-to-read structure that's simple to update. Also, your app's settings are
+generally pre-determined, although you can still modify the collection at runtime.</p>
+
+<p>Each {@link android.preference.Preference} subclass can be declared with an XML element that
+matches the class name, such as {@code &lt;CheckBoxPreference>}.</p>
+
+<p>You must save the XML file in the {@code res/xml/} directory. Although you can name the file
+anything you want, it's traditionally named {@code 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 {@link android.preference.PreferenceScreen}.</p>
+
+<p class="note"><strong>Note:</strong> If you want to create a multi-pane layout for your
+settings, then you need separate XML files for each fragment.</p>
+
+<p>The root node for the XML file must be a {@link android.preference.PreferenceScreen
+&lt;PreferenceScreen&gt;} element. Within this element is where you add each {@link
+android.preference.Preference}. Each child you add within the
+{@link android.preference.PreferenceScreen &lt;PreferenceScreen&gt;} element appears as a single
+item in the list of settings.</p>
+
+<p>For example:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;CheckBoxPreference
+ android:key="pref_sync"
+ android:title="@string/pref_sync"
+ android:summary="@string/pref_sync_summ"
+ android:defaultValue="true" />
+ &lt;ListPreference
+ android:dependency="pref_sync"
+ android:key="pref_syncConnectionType"
+ android:title="@string/pref_syncConnectionType"
+ android:dialogTitle="@string/pref_syncConnectionType"
+ android:entries="@array/pref_syncConnectionTypes_entries"
+ android:entryValues="@array/pref_syncConnectionTypes_values"
+ android:defaultValue="@string/pref_syncConnectionTypes_default" >
+&lt;/PreferenceScreen>
+</pre>
+
+<p>In this example, there's a {@link android.preference.CheckBoxPreference} and a {@link
+android.preference.ListPreference}. Both items include the following three attributes:</p>
+
+<dl>
+ <dt>{@code android:key}</dt>
+ <dd>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 {@link
+android.content.SharedPreferences}.
+ <p>The only instances in which this attribute is <em>not required</em> is when the preference is a
+{@link android.preference.PreferenceCategory} or {@link android.preference.PreferenceScreen}, or the
+preference specifies an {@link android.content.Intent} to invoke (with an <a
+href="#Intents">{@code &lt;intent&gt;}</a> element) or a {@link android.app.Fragment} to display (with an <a
+href="{@docRoot}reference/android/preference/Preference.html#attr_android:fragment">{@code
+android:fragment}</a> attribute).</p>
+ </dd>
+ <dt>{@code android:title}</dt>
+ <dd>This provides a user-visible name for the setting.</dd>
+ <dt>{@code android:defaultValue}</dt>
+ <dd>This specifies the initial value that the system should set in the {@link
+android.content.SharedPreferences} file. You should supply a default value for all
+settings.</dd>
+</dl>
+
+<p>For information about all other supported attributes, see the {@link
+android.preference.Preference} (and respective subclass) documentation.</p>
+
+
+<div class="figure" style="width:300px">
+ <img src="{@docRoot}images/ui/settings/settings-titles.png" alt="" />
+ <p class="img-caption"><strong>Figure 2.</strong> Setting categories
+ with titles. <br/><b>1.</b> The category is specified by the {@link
+android.preference.PreferenceCategory &lt;PreferenceCategory>} element. <br/><b>2.</b> The title is
+specified with the {@code android:title} attribute.</p>
+</div>
+
+
+<p>When your list of settings exceeds about 10 items, you might want to add titles to
+define groups of settings or display those groups in a
+separate screen. These options are described in the following sections.</p>
+
+
+<h3 id="Groups">Creating setting groups</h3>
+
+<p>If you present a list of 10 or more settings, users
+may have difficulty scanning, comprehending, and processing them. You can remedy this by
+dividing some or all of the settings into groups, effectively turning one long list into multiple
+shorter lists. A group of related settings can be presented in one of two ways:</p>
+
+<ul>
+ <li><a href="#Titles">Using titles</a></li>
+ <li><a href="#Subscreens">Using subscreens</a></li>
+</ul>
+
+<p>You can use one or both of these grouping techniques to organize your app's settings. When
+deciding which to use and how to divide your settings, you should follow the guidelines in Android
+Design's <a href="{@docRoot}design/patterns/settings.html">Settings</a> guide.</p>
+
+
+<h4 id="Titles">Using titles</h4>
+
+<p>If you want to provide dividers with headings between groups of settings (as shown in figure 2),
+place each group of {@link android.preference.Preference} objects inside a {@link
+android.preference.PreferenceCategory}.</p>
+
+<p>For example:</p>
+
+<pre>
+&lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;PreferenceCategory
+ android:title="&#64;string/pref_sms_storage_title"
+ android:key="pref_key_storage_settings">
+ &lt;CheckBoxPreference
+ android:key="pref_key_auto_delete"
+ android:summary="&#64;string/pref_summary_auto_delete"
+ android:title="&#64;string/pref_title_auto_delete"
+ android:defaultValue="false"... />
+ &lt;Preference
+ android:key="pref_key_sms_delete_limit"
+ android:dependency="pref_key_auto_delete"
+ android:summary="&#64;string/pref_summary_delete_limit"
+ android:title="&#64;string/pref_title_sms_delete"... />
+ &lt;Preference
+ android:key="pref_key_mms_delete_limit"
+ android:dependency="pref_key_auto_delete"
+ android:summary="&#64;string/pref_summary_delete_limit"
+ android:title="&#64;string/pref_title_mms_delete" ... />
+ &lt;/PreferenceCategory>
+ ...
+&lt;/PreferenceScreen>
+</pre>
+
+
+<h4 id="Subscreens">Using subscreens</h4>
+
+<p>If you want to place groups of settings into a subscreen (as shown in figure 3), place the group
+of {@link android.preference.Preference} objects inside a {@link
+android.preference.PreferenceScreen}.</p>
+
+<img src="{@docRoot}images/ui/settings/settings-subscreen.png" alt="" />
+<p class="img-caption"><strong>Figure 3.</strong> Setting subscreens. The {@code
+&lt;PreferenceScreen>} element
+creates an item that, when selected, opens a separate list to display the nested settings.</p>
+
+<p>For example:</p>
+
+<pre>
+&lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;!-- opens a subscreen of settings -->
+ &lt;PreferenceScreen
+ android:key="button_voicemail_category_key"
+ android:title="&#64;string/voicemail"
+ android:persistent="false">
+ &lt;ListPreference
+ android:key="button_voicemail_provider_key"
+ android:title="&#64;string/voicemail_provider" ... />
+ &lt;!-- opens another nested subscreen -->
+ &lt;PreferenceScreen
+ android:key="button_voicemail_setting_key"
+ android:title="&#64;string/voicemail_settings"
+ android:persistent="false">
+ ...
+ &lt;/PreferenceScreen>
+ &lt;RingtonePreference
+ android:key="button_voicemail_ringtone_key"
+ android:title="&#64;string/voicemail_ringtone_title"
+ android:ringtoneType="notification" ... />
+ ...
+ &lt;/PreferenceScreen>
+ ...
+&lt;/PreferenceScreen>
+</pre>
+
+
+<h3 id="Intents">Using intents</h3>
+
+<p>In some cases, you might want a preference item to open a different activity instead of a
+settings screen, such as a web browser to view a web page. To invoke an {@link
+android.content.Intent} when the user selects a preference item, add an {@code &lt;intent&gt;}
+element as a child of the corresponding {@code &lt;Preference&gt;} element.</p>
+
+<p>For example, here's how you can use a preference item to open a web page:</p>
+
+<pre>
+&lt;Preference android:title="@string/prefs_web_page" >
+ &lt;intent android:action="android.intent.action.VIEW"
+ android:data="http://www.example.com" />
+&lt;/Preference>
+</pre>
+
+<p>You can create both implicit and explicit intents using the following attributes:</p>
+
+<dl>
+ <dt>{@code android:action}</dt>
+ <dd>The action to assign, as per the {@link android.content.Intent#setAction setAction()}
+method.</dd>
+ <dt>{@code android:data}</dt>
+ <dd>The data to assign, as per the {@link android.content.Intent#setData setData()} method.</dd>
+ <dt>{@code android:mimeType}</dt>
+ <dd>The MIME type to assign, as per the {@link android.content.Intent#setType setType()}
+method.</dd>
+ <dt>{@code android:targetClass}</dt>
+ <dd>The class part of the component name, as per the {@link android.content.Intent#setComponent
+setComponent()} method.</dd>
+ <dt>{@code android:targetPackage}</dt>
+ <dd>The package part of the component name, as per the {@link
+android.content.Intent#setComponent setComponent()} method.</dd>
+</dl>
+
+
+
+<h2 id="Activity">Creating a Preference Activity</h2>
+
+<p>To display your settings in an activity, extend the {@link
+android.preference.PreferenceActivity} class. This is an extension of the traditional {@link
+android.app.Activity} class that displays a list of settings based on a hierarchy of {@link
+android.preference.Preference} objects. The {@link android.preference.PreferenceActivity}
+automatically persists the settings associated with each {@link
+android.preference.Preference} when the user makes a change.</p>
+
+<p class="note"><strong>Note:</strong> If you're developing your application for Android 3.0 and
+higher, you should instead use {@link android.preference.PreferenceFragment}. Go to the next
+section about <a href="#Fragment">Using Preference Fragments</a>.</p>
+
+<p>The most important thing to remember is that you do not load a layout of views during the {@link
+android.preference.PreferenceActivity#onCreate onCreate()} callback. Instead, you call {@link
+android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()} to
+add the preferences you've declared in an XML file to the activity. For example, here's the bare
+minimum code required for a functional {@link android.preference.PreferenceActivity}:</p>
+
+<pre>
+public class SettingsActivity extends PreferenceActivity {
+ &#64;Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.preferences);
+ }
+}
+</pre>
+
+<p>This is actually enough code for some apps, because as soon as the user modifies a preference,
+the system saves the changes to a default {@link android.content.SharedPreferences} file that your
+other application components can read when you need to check the user's settings. Many apps,
+however, require a little more code in order to listen for changes that occur to the preferences.
+For information about listening to changes in the {@link android.content.SharedPreferences} file,
+see the section about <a href="#ReadingPrefs">Reading Preferences</a>.</p>
+
+
+
+
+<h2 id="Fragment">Using Preference Fragments</h2>
+
+<p>If you're developing for Android 3.0 (API level 11) and higher, you should use a {@link
+android.preference.PreferenceFragment} to display your list of {@link android.preference.Preference}
+objects. You can add a {@link android.preference.PreferenceFragment} to any activity&mdash;you don't
+need to use {@link android.preference.PreferenceActivity}.</p>
+
+<p><a href="{@docRoot}guide/components/fragments.html">Fragments</a> provide a more
+flexible architecture for your application, compared to using activities alone, no matter what kind
+of activity you're building. As such, we suggest you use {@link
+android.preference.PreferenceFragment} to control the display of your settings instead of {@link
+android.preference.PreferenceActivity} when possible.</p>
+
+<p>Your implementation of {@link android.preference.PreferenceFragment} can be as simple as
+defining the {@link android.preference.PreferenceFragment#onCreate onCreate()} method to load a
+preferences file with {@link android.preference.PreferenceFragment#addPreferencesFromResource
+addPreferencesFromResource()}. For example:</p>
+
+<pre>
+public static class SettingsFragment extends PreferenceFragment {
+ &#64;Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Load the preferences from an XML resource
+ addPreferencesFromResource(R.xml.preferences);
+ }
+ ...
+}
+</pre>
+
+<p>You can then add this fragment to an {@link android.app.Activity} just as you would for any other
+{@link android.app.Fragment}. For example:</p>
+
+<pre>
+public class SettingsActivity extends Activity {
+ &#64;Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Display the fragment as the main content.
+ getFragmentManager().beginTransaction()
+ .replace(android.R.id.content, new SettingsFragment())
+ .commit();
+ }
+}
+</pre>
+
+<p class="note"><strong>Note:</strong> A {@link android.preference.PreferenceFragment} doesn't have
+a its own {@link android.content.Context} object. If you need a {@link android.content.Context}
+object, you can call {@link android.app.Fragment#getActivity()}. However, be careful to call
+{@link android.app.Fragment#getActivity()} only when the fragment is attached to an activity. When
+the fragment is not yet attached, or was detached during the end of its lifecycle, {@link
+android.app.Fragment#getActivity()} will return null.</p>
+
+
+<h2 id="Defaults">Setting Default Values</h2>
+
+<p>The preferences you create probably define some important behaviors for your application, so it's
+necessary that you initialize the associated {@link android.content.SharedPreferences} file with
+default values for each {@link android.preference.Preference} when the user first opens your
+application.</p>
+
+<p>The first thing you must do is specify a default value for each {@link
+android.preference.Preference}
+object in your XML file using the {@code android:defaultValue} attribute. The value can be any data
+type that is appropriate for the corresponding {@link android.preference.Preference} object. For
+example:</p>
+
+<pre>
+&lt;!-- default value is a boolean -->
+&lt;CheckBoxPreference
+ android:defaultValue="true"
+ ... />
+
+&lt;!-- default value is a string -->
+&lt;ListPreference
+ android:defaultValue="@string/pref_syncConnectionTypes_default"
+ ... />
+</pre>
+
+<p>Then, from the {@link android.app.Activity#onCreate onCreate()} method in your application's main
+activity&mdash;and in any other activity through which the user may enter your application for the
+first time&mdash;call {@link android.preference.PreferenceManager#setDefaultValues
+setDefaultValues()}:</p>
+
+<pre>
+PreferenceManager.setDefaultValues(this, R.xml.advanced_preferences, false);
+</pre>
+
+<p>Calling this during {@link android.app.Activity#onCreate 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).</p>
+
+<p>This method takes three arguments:</p>
+<ul>
+ <li>Your application {@link android.content.Context}.</li>
+ <li>The resource ID for the preference XML file for which you want to set the default values.</li>
+ <li>A boolean indicating whether the default values should be set more than once.
+<p>When <code>false</code>, the system sets the default values only if this method has never been
+called in the past (or the {@link android.preference.PreferenceManager#KEY_HAS_SET_DEFAULT_VALUES}
+in the default value shared preferences file is false).</p></li>
+</ul>
+
+<p>As long as you set the third argument to <code>false</code>, you can safely call this method
+every time your activity starts without overriding the user's saved preferences by resetting them to
+the defaults. However, if you set it to <code>true</code>, you will override any previous
+values with the defaults.</p>
+
+
+
+<h2 id="PreferenceHeaders">Using Preference Headers</h2>
+
+<p>In rare cases, you might want to design your settings such that the first screen
+displays only a list of <a href="#Subscreens">subscreens</a> (such as in the system Settings app,
+as shown in figures 4 and 5). When you're developing such a design for Android 3.0 and higher, you
+should use a new "headers" feature in Android 3.0, instead of building subscreens with nested
+{@link android.preference.PreferenceScreen} elements.</p>
+
+<p>To build your settings with headers, you need to:</p>
+<ol>
+ <li>Separate each group of settings into separate instances of {@link
+android.preference.PreferenceFragment}. That is, each group of settings needs a separate XML
+file.</li>
+ <li>Create an XML headers file that lists each settings group and declares which fragment
+contains the corresponding list of settings.</li>
+ <li>Extend the {@link android.preference.PreferenceActivity} class to host your settings.</li>
+ <li>Implement the {@link
+android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} callback to specify the
+headers file.</li>
+</ol>
+
+<p>A great benefit to using this design is that {@link android.preference.PreferenceActivity}
+automatically presents the two-pane layout shown in figure 4 when running on large screens.</p>
+
+<p>Even if your application supports versions of Android older than 3.0, you can build your
+application to use {@link android.preference.PreferenceFragment} for a two-pane presentation on
+newer devices while still supporting a traditional multi-screen hierarchy on older
+devices (see the section about <a href="#BackCompatHeaders">Supporting older versions with
+preference headers</a>).</p>
+
+<img src="{@docRoot}images/ui/settings/settings-headers-tablet.png" alt="" />
+<p class="img-caption"><strong>Figure 4.</strong> Two-pane layout with headers. <br/><b>1.</b> The
+headers are defined with an XML headers file. <br/><b>2.</b> Each group of settings is defined by a
+{@link android.preference.PreferenceFragment} that's specified by a {@code &lt;header>} element in
+the headers file.</p>
+
+<img src="{@docRoot}images/ui/settings/settings-headers-handset.png" alt="" />
+<p class="img-caption"><strong>Figure 5.</strong> A handset device with setting headers. When an
+item is selected, the associated {@link android.preference.PreferenceFragment} replaces the
+headers.</p>
+
+
+<h3 id="CreateHeaders" style="clear:left">Creating the headers file</h3>
+
+<p>Each group of settings in your list of headers is specified by a single {@code &lt;header>}
+element inside a root {@code &lt;preference-headers>} element. For example:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;header
+ android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentOne"
+ android:title="@string/prefs_category_one"
+ android:summary="@string/prefs_summ_category_one" />
+ &lt;header
+ android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentTwo"
+ android:title="@string/prefs_category_two"
+ android:summary="@string/prefs_summ_category_two" >
+ &lt;!-- key/value pairs can be included as arguments for the fragment. -->
+ &lt;extra android:name="someKey" android:value="someHeaderValue" />
+ &lt;/header>
+&lt;/preference-headers>
+</pre>
+
+<p>With the {@code android:fragment} attribute, each header declares an instance of {@link
+android.preference.PreferenceFragment} that should open when the user selects the header.</p>
+
+<p>The {@code &lt;extras>} element allows you to pass key-value pairs to the fragment in a {@link
+android.os.Bundle}. The fragment can retrieve the arguments by calling {@link
+android.app.Fragment#getArguments()}. You might pass arguments to the fragment for a variety of
+reasons, but one good reason is to reuse the same subclass of {@link
+android.preference.PreferenceFragment} for each group and use the argument to specify which
+preferences XML file the fragment should load.</p>
+
+<p>For example, here's a fragment that can be reused for multiple settings groups, when each
+header defines an {@code &lt;extra>} argument with the {@code "settings"} key:</p>
+
+<pre>
+public static class SettingsFragment extends PreferenceFragment {
+ &#64;Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ String settings = getArguments().getString("settings");
+ if ("notifications".equals(settings)) {
+ addPreferencesFromResource(R.xml.settings_wifi);
+ } else if ("sync".equals(settings)) {
+ addPreferencesFromResource(R.xml.settings_sync);
+ }
+ }
+}
+</pre>
+
+
+
+<h3 id="DisplayHeaders">Displaying the headers</h3>
+
+<p>To display the preference headers, you must implement the {@link
+android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} callback method and call
+{@link android.preference.PreferenceActivity#loadHeadersFromResource
+loadHeadersFromResource()}. For example:</p>
+
+<pre>
+public class SettingsActivity extends PreferenceActivity {
+ &#64;Override
+ public void onBuildHeaders(List&lt;Header> target) {
+ loadHeadersFromResource(R.xml.preference_headers, target);
+ }
+}
+</pre>
+
+<p>When the user selects an item from the list of headers, the system opens the associated {@link
+android.preference.PreferenceFragment}.</p>
+
+<p class="note"><strong>Note:</strong> When using preference headers, your subclass of {@link
+android.preference.PreferenceActivity} doesn't need to implement the {@link
+android.preference.PreferenceActivity#onCreate onCreate()} method, because the only required
+task for the activity is to load the headers.</p>
+
+
+<h3 id="BackCompatHeaders">Supporting older versions with preference headers</h3>
+
+<p>If your application supports versions of Android older than 3.0, you can still use headers to
+provide a two-pane layout when running on Android 3.0 and higher. All you need to do is create an
+additional preferences XML file that uses basic {@link android.preference.Preference
+&lt;Preference>} elements that behave like the header items (to be used by the older Android
+versions).</p>
+
+<p>Instead of opening a new {@link android.preference.PreferenceScreen}, however, each of the {@link
+android.preference.Preference &lt;Preference>} elements sends an {@link android.content.Intent} to
+the {@link android.preference.PreferenceActivity} that specifies which preference XML file to
+load.</p>
+
+<p>For example, here's an XML file for preference headers that is used on Android 3.0
+and higher ({@code res/xml/preference_headers.xml}):</p>
+
+<pre>
+&lt;preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;header
+ android:fragment="com.example.prefs.SettingsFragmentOne"
+ android:title="@string/prefs_category_one"
+ android:summary="@string/prefs_summ_category_one" />
+ &lt;header
+ android:fragment="com.example.prefs.SettingsFragmentTwo"
+ android:title="@string/prefs_category_two"
+ android:summary="@string/prefs_summ_category_two" />
+&lt;/preference-headers>
+</pre>
+
+<p>And here is a preference file that provides the same headers for versions older than
+Android 3.0 ({@code res/xml/preference_headers_legacy.xml}):</p>
+
+<pre>
+&lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;Preference
+ android:title="@string/prefs_category_one"
+ android:summary="@string/prefs_summ_category_one" >
+ &lt;intent
+ android:targetPackage="com.example.prefs"
+ android:targetClass="com.example.prefs.SettingsActivity"
+ android:action="com.example.prefs.PREFS_ONE" />
+ &lt;/Preference>
+ &lt;Preference
+ android:title="@string/prefs_category_two"
+ android:summary="@string/prefs_summ_category_two" >
+ &lt;intent
+ android:targetPackage="com.example.prefs"
+ android:targetClass="com.example.prefs.SettingsActivity"
+ android:action="com.example.prefs.PREFS_TWO" />
+ &lt;/Preference>
+&lt;/PreferenceScreen>
+</pre>
+
+<p>Because support for {@code &lt;preference-headers>} was added in Android 3.0, the system calls
+{@link android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} in your {@link
+android.preference.PreferenceActivity} only when running on Androd 3.0 or higher. In order to load
+the "legacy" headers file ({@code preference_headers_legacy.xml}), you must check the Android
+version and, if the version is older than Android 3.0 ({@link
+android.os.Build.VERSION_CODES#HONEYCOMB}), call {@link
+android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()} to
+load the legacy header file. For example:</p>
+
+<pre>
+&#64;Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ...
+
+ if (Build.VERSION.SDK_INT &lt; Build.VERSION_CODES.HONEYCOMB) {
+ // Load the legacy preferences headers
+ addPreferencesFromResource(R.xml.preference_headers_legacy);
+ }
+}
+
+// Called only on Honeycomb and later
+&#64;Override
+public void onBuildHeaders(List&lt;Header> target) {
+ loadHeadersFromResource(R.xml.preference_headers, target);
+}
+</pre>
+
+<p>The only thing left to do is handle the {@link android.content.Intent} that's passed into the
+activity to identify which preference file to load. So retrieve the intent's action and compare it
+to known action strings that you've used in the preference XML's {@code &lt;intent>} tags:</p>
+
+<pre>
+final static String ACTION_PREFS_ONE = "com.example.prefs.PREFS_ONE";
+...
+
+&#64;Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ String action = getIntent().getAction();
+ if (action != null &amp;&amp; action.equals(ACTION_PREFS_ONE)) {
+ addPreferencesFromResource(R.xml.preferences);
+ }
+ ...
+
+ else if (Build.VERSION.SDK_INT &lt; Build.VERSION_CODES.HONEYCOMB) {
+ // Load the legacy preferences headers
+ addPreferencesFromResource(R.xml.preference_headers_legacy);
+ }
+}
+</pre>
+
+<p>Beware that consecutive calls to {@link
+android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()} will
+stack all the preferences in a single list, so be sure that it's only called once by chaining the
+conditions with else-if statements.</p>
+
+
+
+
+
+<h2 id="ReadingPrefs">Reading Preferences</h2>
+
+<p>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 {@link
+android.preference.PreferenceManager#getDefaultSharedPreferences
+PreferenceManager.getDefaultSharedPreferences()}. This returns the {@link
+android.content.SharedPreferences} object containing all the key-value pairs that are associated
+with the {@link android.preference.Preference} objects used in your {@link
+android.preference.PreferenceActivity}.</p>
+
+<p>For example, here's how you can read one of the preference values from any other activity in your
+application:</p>
+
+<pre>
+SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
+String syncConnPref = sharedPref.getString(SettingsActivity.KEY_PREF_SYNC_CONN, "");
+</pre>
+
+
+
+<h3 id="Listening">Listening for preference changes</h3>
+
+<p>There are several reasons you might want to be notified as soon as the use changes one of the
+preferences. In order to receive a callback when a change happens to any one of the preferences,
+implement the {@link android.content.SharedPreferences.OnSharedPreferenceChangeListener
+SharedPreference.OnSharedPreferenceChangeListener} interface and register the listener for the
+{@link android.content.SharedPreferences} object by calling {@link
+android.content.SharedPreferences#registerOnSharedPreferenceChangeListener
+registerOnSharedPreferenceChangeListener()}.</p>
+
+<p>The interface has only one callback method, {@link
+android.content.SharedPreferences.OnSharedPreferenceChangeListener#onSharedPreferenceChanged
+onSharedPreferenceChanged()}, and you might find it easiest to implement the interface as a part of
+your activity. For example:</p>
+
+<pre>
+public class SettingsActivity extends PreferenceActivity
+ implements OnSharedPreferenceChangeListener {
+ public static final String KEY_PREF_SYNC_CONN = "pref_syncConnectionType";
+ ...
+
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ if (key.equals(KEY_PREF_SYNC_CONN)) {
+ Preference connectionPref = findPreference(key);
+ // Set summary to be the user-description for the selected value
+ connectionPref.setSummary(sharedPreferences.getString(key, ""));
+ }
+ }
+}
+</pre>
+
+<p>In this example, the method checks whether the changed setting is for a known preference key. It
+calls {@link android.preference.PreferenceActivity#findPreference findPreference()} to get the
+{@link android.preference.Preference} object that was changed so it can modify the item's
+summary to be a description of the user's selection. That is, when the setting is a {@link
+android.preference.ListPreference} or other multiple choice setting, you should call {@link
+android.preference.Preference#setSummary setSummary()} when the setting changes to display the
+current status (such as the Sleep setting shown in figure 5).</p>
+
+<p class="note"><strong>Note:</strong> As described in the Android Design document about <a
+href="{@docRoot}design/patterns/settings.html">Settings</a>, we recommend that you update the
+summary for a {@link android.preference.ListPreference} each time the user changes the preference in
+order to describe the current setting.</p>
+
+<p>For proper lifecycle management in the activity, we recommend that you register and unregister
+your {@link android.content.SharedPreferences.OnSharedPreferenceChangeListener} during the {@link
+android.app.Activity#onResume} and {@link android.app.Activity#onPause} callbacks, respectively:</p>
+
+<pre>
+&#64;Override
+protected void onResume() {
+ super.onResume();
+ getPreferenceScreen().getSharedPreferences()
+ .registerOnSharedPreferenceChangeListener(this);
+}
+
+&#64;Override
+protected void onPause() {
+ super.onPause();
+ getPreferenceScreen().getSharedPreferences()
+ .unregisterOnSharedPreferenceChangeListener(this);
+}
+</pre>
+
+
+
+<h2 id="NetworkUsage">Managing Network Usage</h2>
+
+
+<p>Beginning with Android 4.0, the system's Settings application allows users to see how much
+network data their applications are using while in the foreground and background. Users can then
+disable the use of background data for individual apps. In order to avoid users disabling your app's
+access to data from the background, you should use the data connection efficiently and allow
+users to refine your app's data usage through your application settings.<p>
+
+<p>For example, you might allow the user to control how often your app syncs data, whether your app
+performs uploads/downloads only when on Wi-Fi, whether your app uses data while roaming, etc. With
+these controls available to them, users are much less likely to disable your app's access to data
+when they approach the limits they set in the system Settings, because they can instead precisely
+control how much data your app uses.</p>
+
+<p>Once you've added the necessary preferences in your {@link android.preference.PreferenceActivity}
+to control your app's data habits, you should add an intent filter for {@link
+android.content.Intent#ACTION_MANAGE_NETWORK_USAGE} in your manifest file. For example:</p>
+
+<pre>
+&lt;activity android:name="SettingsActivity" ... >
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
+ &lt;category android:name="android.intent.category.DEFAULT" />
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p>This intent filter indicates to the system that this is the activity that controls your
+application's data usage. Thus, when the user inspects how much data your app is using from the
+system's Settings app, a <em>View application settings</em> button is available that launches your
+{@link android.preference.PreferenceActivity} so the user can refine how much data your app
+uses.</p>
+
+
+
+
+
+
+
+<h2 id="Custom">Building a Custom Preference</h2>
+
+<p>The Android framework includes a variety of {@link android.preference.Preference} subclasses that
+allow you to build a UI for several different types of settings.
+However, you might discover a setting you need for which there’s no built-in solution, such as a
+number picker or date picker. In such a case, you’ll need to create a custom preference by extending
+the {@link android.preference.Preference} class or one of the other subclasses.</p>
+
+<p>When you extend the {@link android.preference.Preference} class, there are a few important
+things you need to do:</p>
+
+<ul>
+ <li>Specify the user interface that appears when the user selects the settings.</li>
+ <li>Save the setting's value when appropriate.</li>
+ <li>Initialize the {@link android.preference.Preference} with the current (or default) value
+when it comes into view.</li>
+ <li>Provide the default value when requested by the system.</li>
+ <li>If the {@link android.preference.Preference} provides its own UI (such as a dialog), save
+and restore the state to handle lifecycle changes (such as when the user rotates the screen).</li>
+</ul>
+
+<p>The following sections describe how to accomplish each of these tasks.</p>
+
+
+
+<h3 id="CustomSelected">Specifying the user interface</h3>
+
+ <p>If you directly extend the {@link android.preference.Preference} class, you need to implement
+{@link android.preference.Preference#onClick()} to define the action that occurs when the user
+selects the item. However, most custom settings extend {@link android.preference.DialogPreference} to
+show a dialog, which simplifies the procedure. When you extend {@link
+android.preference.DialogPreference}, you must call {@link
+android.preference.DialogPreference#setDialogLayoutResource setDialogLayoutResourcs()} during in the
+class constructor to specify the layout for the dialog.</p>
+
+ <p>For example, here's the constructor for a custom {@link
+android.preference.DialogPreference} that declares the layout and specifies the text for the
+default positive and negative dialog buttons:</p>
+
+<pre>
+public class NumberPickerPreference extends DialogPreference {
+ public NumberPickerPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ setDialogLayoutResource(R.layout.numberpicker_dialog);
+ setPositiveButtonText(android.R.string.ok);
+ setNegativeButtonText(android.R.string.cancel);
+
+ setDialogIcon(null);
+ }
+ ...
+}
+</pre>
+
+
+
+<h3 id="CustomSave">Saving the setting's value</h3>
+
+<p>You can save a value for the setting at any time by calling one of the {@link
+android.preference.Preference} class's {@code persist*()} methods, such as {@link
+android.preference.Preference#persistInt persistInt()} if the setting's value is an integer or
+{@link android.preference.Preference#persistBoolean persistBoolean()} to save a boolean.</p>
+
+<p class="note"><strong>Note:</strong> Each {@link android.preference.Preference} can save only one
+data type, so you must use the {@code persist*()} method appropriate for the data type used by your
+custom {@link android.preference.Preference}.</p>
+
+<p>When you choose to persist the setting can depend on which {@link
+android.preference.Preference} class you extend. If you extend {@link
+android.preference.DialogPreference}, then you should persist the value only when the dialog
+closes due to a positive result (the user selects the "OK" button).</p>
+
+<p>When a {@link android.preference.DialogPreference} closes, the system calls the {@link
+android.preference.DialogPreference#onDialogClosed onDialogClosed()} method. The method includes a
+boolean argument that specifies whether the user result is "positive"&mdash;if the value is
+<code>true</code>, then the user selected the positive button and you should save the new value. For
+example:</p>
+
+<pre>
+&#64;Override
+protected void onDialogClosed(boolean positiveResult) {
+ // When the user selects "OK", persist the new value
+ if (positiveResult) {
+ persistInt(mNewValue);
+ }
+}
+</pre>
+
+<p>In this example, <code>mNewValue</code> is a class member that holds the setting's current
+value. Calling {@link android.preference.Preference#persistInt persistInt()} saves the value to
+the {@link android.content.SharedPreferences} file (automatically using the key that's
+specified in the XML file for this {@link android.preference.Preference}).</p>
+
+
+<h3 id="CustomInitialize">Initializing the current value</h3>
+
+<p>When the system adds your {@link android.preference.Preference} to the screen, it
+calls {@link android.preference.Preference#onSetInitialValue onSetInitialValue()} to notify
+you whether the setting has a persisted value. If there is no persisted value, this call provides
+you the default value.</p>
+
+<p>The {@link android.preference.Preference#onSetInitialValue onSetInitialValue()} method passes
+a boolean, <code>restorePersistedValue</code>, to indicate whether a value has already been persisted
+for the setting. If it is <code>true</code>, then you should retrieve the persisted value by calling
+one of the {@link
+android.preference.Preference} class's {@code getPersisted*()} methods, such as {@link
+android.preference.Preference#getPersistedInt getPersistedInt()} for an integer value. You'll
+usually want to retrieve the persisted value so you can properly update the UI to reflect the
+previously saved value.</p>
+
+<p>If <code>restorePersistedValue</code> is <code>false</code>, then you
+should use the default value that is passed in the second argument.</p>
+
+<pre>
+&#64;Override
+protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
+ if (restorePersistedValue) {
+ // Restore existing state
+ mCurrentValue = this.getPersistedInt(DEFAULT_VALUE);
+ } else {
+ // Set default state from the XML attribute
+ mCurrentValue = (Integer) defaultValue;
+ persistInt(mCurrentValue);
+ }
+}
+</pre>
+
+<p>Each {@code getPersisted*()} method takes an argument that specifies the
+default value to use in case there is actually no persisted value or the key does not exist. In
+the example above, a local constant is used to specify the default value in case {@link
+android.preference.Preference#getPersistedInt getPersistedInt()} can't return a persisted value.</p>
+
+<p class="caution"><strong>Caution:</strong> You <strong>cannot</strong> use the
+<code>defaultValue</code> as the default value in the {@code getPersisted*()} method, because
+its value is always null when <code>restorePersistedValue</code> is <code>true</code>.</p>
+
+
+<h3 id="CustomDefault">Providing a default value</h3>
+
+<p>If the instance of your {@link android.preference.Preference} class specifies a default value
+(with the {@code android:defaultValue} attribute), then the
+system calls {@link android.preference.Preference#onGetDefaultValue
+onGetDefaultValue()} when it instantiates the object in order to retrieve the value. You must
+implement this method in order for the system to save the default value in the {@link
+android.content.SharedPreferences}. For example:</p>
+
+<pre>
+&#64;Override
+protected Object onGetDefaultValue(TypedArray a, int index) {
+ return a.getInteger(index, DEFAULT_VALUE);
+}
+</pre>
+
+<p>The method arguments provide everything you need: the array of attributes and the index
+position of the {@code android:defaultValue}, which you must retrieve. The reason you must
+implement this method to extract the default value from the attribute is because you must specify
+a local default value for the attribute in case the value is undefined.</p>
+
+
+
+<h3 id="CustomSaveState">Saving and restoring the Preference's state</h3>
+
+<p>Just like a {@link android.view.View} in a layout, your {@link android.preference.Preference}
+subclass is responsible for saving and restoring its state in case the activity or fragment is
+restarted (such as when the user rotates the screen). To properly save and
+restore the state of your {@link android.preference.Preference} class, you must implement the
+lifecycle callback methods {@link android.preference.Preference#onSaveInstanceState
+onSaveInstanceState()} and {@link
+android.preference.Preference#onRestoreInstanceState onRestoreInstanceState()}.</p>
+
+<p>The state of your {@link android.preference.Preference} is defined by an object that implements
+the {@link android.os.Parcelable} interface. The Android framework provides such an object for you
+as a starting point to define your state object: the {@link
+android.preference.Preference.BaseSavedState} class.</p>
+
+<p>To define how your {@link android.preference.Preference} class saves its state, you should
+extend the {@link android.preference.Preference.BaseSavedState} class. You need to override just
+ a few methods and define the {@link android.preference.Preference.BaseSavedState#CREATOR}
+object.</p>
+
+<p>For most apps, you can copy the following implementation and simply change the lines that
+handle the {@code value} if your {@link android.preference.Preference} subclass saves a data
+type other than an integer.</p>
+
+<pre>
+private static class SavedState extends BaseSavedState {
+ // Member that holds the setting's value
+ // Change this data type to match the type saved by your Preference
+ int value;
+
+ public SavedState(Parcelable superState) {
+ super(superState);
+ }
+
+ public SavedState(Parcel source) {
+ super(source);
+ // Get the current preference's value
+ value = source.readInt(); // Change this to read the appropriate data type
+ }
+
+ &#64;Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ // Write the preference's value
+ dest.writeInt(value); // Change this to write the appropriate data type
+ }
+
+ // Standard creator object using an instance of this class
+ public static final Parcelable.Creator&lt;SavedState> CREATOR =
+ new Parcelable.Creator&lt;SavedState>() {
+
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+}
+</pre>
+
+<p>With the above implementation of {@link android.preference.Preference.BaseSavedState} added
+to your app (usually as a subclass of your {@link android.preference.Preference} subclass), you
+then need to implement the {@link android.preference.Preference#onSaveInstanceState
+onSaveInstanceState()} and {@link
+android.preference.Preference#onRestoreInstanceState onRestoreInstanceState()} methods for your
+{@link android.preference.Preference} subclass.</p>
+
+<p>For example:</p>
+
+<pre>
+&#64;Override
+protected Parcelable onSaveInstanceState() {
+ final Parcelable superState = super.onSaveInstanceState();
+ // Check whether this Preference is persistent (continually saved)
+ if (isPersistent()) {
+ // No need to save instance state since it's persistent, use superclass state
+ return superState;
+ }
+
+ // Create instance of custom BaseSavedState
+ final SavedState myState = new SavedState(superState);
+ // Set the state's value with the class member that holds current setting value
+ myState.value = mNewValue;
+ return myState;
+}
+
+&#64;Override
+protected void onRestoreInstanceState(Parcelable state) {
+ // Check whether we saved the state in onSaveInstanceState
+ if (state == null || !state.getClass().equals(SavedState.class)) {
+ // Didn't save the state, so call superclass
+ super.onRestoreInstanceState(state);
+ return;
+ }
+
+ // Cast state to custom BaseSavedState and pass to superclass
+ SavedState myState = (SavedState) state;
+ super.onRestoreInstanceState(myState.getSuperState());
+
+ // Set this Preference's widget to reflect the restored state
+ mNumberPicker.setValue(myState.value);
+}
+</pre>
+
diff --git a/docs/html/images/ui/settings/settings-headers-handset.png b/docs/html/images/ui/settings/settings-headers-handset.png
new file mode 100644
index 0000000..d04ad17
--- /dev/null
+++ b/docs/html/images/ui/settings/settings-headers-handset.png
Binary files differ
diff --git a/docs/html/images/ui/settings/settings-headers-tablet.png b/docs/html/images/ui/settings/settings-headers-tablet.png
new file mode 100644
index 0000000..d0da5f2
--- /dev/null
+++ b/docs/html/images/ui/settings/settings-headers-tablet.png
Binary files differ
diff --git a/docs/html/images/ui/settings/settings-subscreen.png b/docs/html/images/ui/settings/settings-subscreen.png
new file mode 100644
index 0000000..17de231
--- /dev/null
+++ b/docs/html/images/ui/settings/settings-subscreen.png
Binary files differ
diff --git a/docs/html/images/ui/settings/settings-titles.png b/docs/html/images/ui/settings/settings-titles.png
new file mode 100644
index 0000000..df4e1b4
--- /dev/null
+++ b/docs/html/images/ui/settings/settings-titles.png
Binary files differ
diff --git a/docs/html/images/ui/settings/settings.png b/docs/html/images/ui/settings/settings.png
new file mode 100644
index 0000000..db9976c
--- /dev/null
+++ b/docs/html/images/ui/settings/settings.png
Binary files differ