summaryrefslogtreecommitdiffstats
path: root/core/java/android/preference
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2010-08-02 17:30:33 -0700
committerDianne Hackborn <hackbod@google.com>2010-08-03 11:18:23 -0700
commitb1ad5977bc8178b6d350ebe9099daded4c1ef603 (patch)
tree89acc2cb818bf5acbb18a4614c6313df95c013f0 /core/java/android/preference
parentee9907b4619ea9f3551ee7f5a2c5a803e3ee636c (diff)
downloadframeworks_base-b1ad5977bc8178b6d350ebe9099daded4c1ef603.zip
frameworks_base-b1ad5977bc8178b6d350ebe9099daded4c1ef603.tar.gz
frameworks_base-b1ad5977bc8178b6d350ebe9099daded4c1ef603.tar.bz2
New two-pane mode for PreferenceActivity.
This introduces a whole new way to use PreferenceActivity, as a container for PreferenceFragments that the user can switch between from a list of headers. Change-Id: I1c79b7c78b86790dc460a1414a999aba5de80628
Diffstat (limited to 'core/java/android/preference')
-rw-r--r--core/java/android/preference/PreferenceActivity.java522
-rw-r--r--core/java/android/preference/PreferenceFragment.java30
2 files changed, 462 insertions, 90 deletions
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 4686978..fdc874b 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -16,71 +16,96 @@
package android.preference;
-import android.app.Activity;
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.app.Fragment;
import android.app.ListActivity;
+import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
+import android.content.res.Configuration;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Xml;
+import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
import android.view.View.OnClickListener;
+import android.widget.ArrayAdapter;
import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
/**
- * Shows a hierarchy of {@link Preference} objects as
- * lists, possibly spanning multiple screens. These preferences will
- * automatically save to {@link SharedPreferences} as the user interacts with
- * them. To retrieve an instance of {@link SharedPreferences} that the
- * preference hierarchy in this activity will use, call
- * {@link PreferenceManager#getDefaultSharedPreferences(android.content.Context)}
- * with a context in the same package as this activity.
- * <p>
- * Furthermore, the preferences shown will follow the visual style of system
- * preferences. It is easy to create a hierarchy of preferences (that can be
- * shown on multiple screens) via XML. For these reasons, it is recommended to
- * use this activity (as a superclass) to deal with preferences in applications.
- * <p>
- * A {@link PreferenceScreen} object should be at the top of the preference
- * hierarchy. Furthermore, subsequent {@link PreferenceScreen} in the hierarchy
- * denote a screen break--that is the preferences contained within subsequent
- * {@link PreferenceScreen} should be shown on another screen. The preference
- * framework handles showing these other screens from the preference hierarchy.
- * <p>
- * The preference hierarchy can be formed in multiple ways:
- * <li> From an XML file specifying the hierarchy
- * <li> From different {@link Activity Activities} that each specify its own
- * preferences in an XML file via {@link Activity} meta-data
- * <li> From an object hierarchy rooted with {@link PreferenceScreen}
- * <p>
- * To inflate from XML, use the {@link #addPreferencesFromResource(int)}. The
- * root element should be a {@link PreferenceScreen}. Subsequent elements can point
- * to actual {@link Preference} subclasses. As mentioned above, subsequent
- * {@link PreferenceScreen} in the hierarchy will result in the screen break.
- * <p>
- * To specify an {@link Intent} to query {@link Activity Activities} that each
- * have preferences, use {@link #addPreferencesFromIntent}. Each
- * {@link Activity} can specify meta-data in the manifest (via the key
- * {@link PreferenceManager#METADATA_KEY_PREFERENCES}) that points to an XML
- * resource. These XML resources will be inflated into a single preference
- * hierarchy and shown by this activity.
- * <p>
- * To specify an object hierarchy rooted with {@link PreferenceScreen}, use
- * {@link #setPreferenceScreen(PreferenceScreen)}.
- * <p>
- * As a convenience, this activity implements a click listener for any
- * preference in the current hierarchy, see
- * {@link #onPreferenceTreeClick(PreferenceScreen, Preference)}.
+ * This is the base class for an activity to show a hierarchy of preferences
+ * to the user. Prior to {@link android.os.Build.VERSION_CODES#HONEYCOMB}
+ * this class only allowed the display of a single set of preference; this
+ * functionality should now be found in the new {@link PreferenceFragment}
+ * class. If you are using PreferenceActivity in its old mode, the documentation
+ * there applies to the deprecated APIs here.
+ *
+ * <p>This activity shows one or more headers of preferences, each of with
+ * is associated with a {@link PreferenceFragment} to display the preferences
+ * of that header. The actual layout and display of these associations can
+ * however vary; currently there are two major approaches it may take:
+ *
+ * <ul>
+ * <li>On a small screen it may display only the headers as a single list
+ * when first launched. Selecting one of the header items will re-launch
+ * the activity with it only showing the PreferenceFragment of that header.
+ * <li>On a large screen in may display both the headers and current
+ * PreferenceFragment together as panes. Selecting a header item switches
+ * to showing the correct PreferenceFragment for that item.
+ * </ul>
+ *
+ * <p>Subclasses of PreferenceActivity should implement
+ * {@link #onBuildHeaders} to populate the header list with the desired
+ * items. Doing this implicitly switches the class into its new "headers
+ * + fragments" mode rather than the old style of just showing a single
+ * preferences list.
+ *
+ * <a name="SampleCode"></a>
+ * <h3>Sample Code</h3>
+ *
+ * <p>The following sample code shows a simple preference activity that
+ * has two different sets of preferences. The implementation, consisting
+ * of the activity itself as well as its two preference fragments is:</p>
+ *
+ * {@sample development/samples/ApiDemos/src/com/example/android/apis/preference/PreferenceWithHeaders.java
+ * activity}
*
- * @see Preference
- * @see PreferenceScreen
+ * <p>The preference_headers resource describes the headers to be displayed
+ * and the fragments associated with them. It is:
+ *
+ * {@sample development/samples/ApiDemos/res/xml/preference_headers.xml headers}
+ *
+ * See {@link PreferenceFragment} for information on implementing the
+ * fragments themselves.
*/
public abstract class PreferenceActivity extends ListActivity implements
PreferenceManager.OnPreferenceTreeClickListener {
+ private static final String TAG = "PreferenceActivity";
private static final String PREFERENCES_TAG = "android:preferences";
+ private static final String EXTRA_PREFS_SHOW_FRAGMENT = ":android:show_fragment";
+
+ private static final String EXTRA_PREFS_NO_HEADERS = ":android:no_headers";
+
// extras that allow any preference activity to be launched as part of a wizard
// show Back and Next buttons? takes boolean parameter
@@ -92,12 +117,26 @@ public abstract class PreferenceActivity extends ListActivity implements
private static final String EXTRA_PREFS_SET_NEXT_TEXT = "extra_prefs_set_next_text";
private static final String EXTRA_PREFS_SET_BACK_TEXT = "extra_prefs_set_back_text";
- private Button mNextButton;
+ // --- State for new mode when showing a list of headers + prefs fragment
+
+ private final ArrayList<Header> mHeaders = new ArrayList<Header>();
+
+ private HeaderAdapter mAdapter;
+
+ private View mPrefsContainer;
+
+ private boolean mSinglePane;
+
+ // --- State for old mode when showing a single preference list
private PreferenceManager mPreferenceManager;
private Bundle mSavedInstanceState;
+ // --- Common state
+
+ private Button mNextButton;
+
/**
* The starting request code given out to preference framework.
*/
@@ -116,12 +155,128 @@ public abstract class PreferenceActivity extends ListActivity implements
}
};
+ private class HeaderViewHolder {
+ ImageView icon;
+ TextView title;
+ TextView summary;
+ }
+
+ private class HeaderAdapter extends ArrayAdapter<Header> {
+ private LayoutInflater mInflater;
+
+ public HeaderAdapter(Context context, List<Header> objects) {
+ super(context, 0, objects);
+ mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ HeaderViewHolder holder;
+ View view;
+
+ if (convertView == null) {
+ view = mInflater.inflate(com.android.internal.R.layout.preference_list_item,
+ parent, false);
+ holder = new HeaderViewHolder();
+ holder.icon = (ImageView)view.findViewById(
+ com.android.internal.R.id.icon);
+ holder.title = (TextView)view.findViewById(
+ com.android.internal.R.id.title);
+ holder.summary = (TextView)view.findViewById(
+ com.android.internal.R.id.summary);
+ view.setTag(holder);
+ } else {
+ view = convertView;
+ holder = (HeaderViewHolder)view.getTag();
+ }
+
+ Header header = getItem(position);
+ if (header.icon != null) holder.icon.setImageDrawable(header.icon);
+ else if (header.iconRes != 0) holder.icon.setImageResource(header.iconRes);
+ if (header.title != null) holder.title.setText(header.title);
+ if (header.summary != null) holder.summary.setText(header.summary);
+
+ return view;
+ }
+ }
+
+ /**
+ * Description of a single Header item that the user can select.
+ */
+ public static class Header {
+ /**
+ * Title of the header that is shown to the user.
+ */
+ CharSequence title;
+
+ /**
+ * Optional summary describing what this header controls.
+ */
+ CharSequence summary;
+
+ /**
+ * Optional icon resource to show for this header.
+ */
+ int iconRes;
+
+ /**
+ * Optional icon drawable to show for this header. (If this is non-null,
+ * the iconRes will be ignored.)
+ */
+ Drawable icon;
+
+ /**
+ * Full class name of the fragment to display when this header is
+ * selected.
+ */
+ String fragment;
+ }
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(com.android.internal.R.layout.preference_list_content);
+ mPrefsContainer = findViewById(com.android.internal.R.id.prefs);
+ boolean hidingHeaders = onIsHidingHeaders();
+ mSinglePane = hidingHeaders || !onIsMultiPane();
+ String initialFragment = getIntent().getStringExtra(EXTRA_PREFS_SHOW_FRAGMENT);
+
+ if (initialFragment != null && mSinglePane) {
+ // If we are just showing a fragment, we want to run in
+ // new fragment mode, but don't need to compute and show
+ // the headers.
+ getListView().setVisibility(View.GONE);
+ mPrefsContainer.setVisibility(View.VISIBLE);
+ switchToHeader(initialFragment);
+
+ } else {
+ // We need to try to build the headers.
+ onBuildHeaders(mHeaders);
+
+ // If there are headers, then at this point we need to show
+ // them and, depending on the screen, we may also show in-line
+ // the currently selected preference fragment.
+ if (mHeaders.size() > 0) {
+ mAdapter = new HeaderAdapter(this, mHeaders);
+ setListAdapter(mAdapter);
+ if (!mSinglePane) {
+ mPrefsContainer.setVisibility(View.VISIBLE);
+ switchToHeader(initialFragment != null
+ ? initialFragment : onGetInitialFragment());
+ }
+
+ // If there are no headers, we are in the old "just show a screen
+ // of preferences" mode.
+ } else {
+ mPreferenceManager = new PreferenceManager(this, FIRST_REQUEST_CODE);
+ mPreferenceManager.setOnPreferenceTreeClickListener(this);
+ }
+ }
+
+ getListView().setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
+
// see if we should show Back/Next buttons
Intent intent = getIntent();
if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false)) {
@@ -163,45 +318,165 @@ public abstract class PreferenceActivity extends ListActivity implements
}
}
}
+ }
+
+ /**
+ * Called to determine if the activity should run in multi-pane mode.
+ * The default implementation returns true if the screen is large
+ * enough.
+ */
+ public boolean onIsMultiPane() {
+ Configuration config = getResources().getConfiguration();
+ if ((config.screenLayout&Configuration.SCREENLAYOUT_SIZE_MASK)
+ == Configuration.SCREENLAYOUT_SIZE_XLARGE
+ && config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Called to determine whether the header list should be hidden. The
+ * default implementation hides the list if the activity is being re-launched
+ * when not in multi-pane mode.
+ */
+ public boolean onIsHidingHeaders() {
+ return getIntent().getBooleanExtra(EXTRA_PREFS_NO_HEADERS, false);
+ }
+
+ /**
+ * Called to determine the initial fragment to be shown. The default
+ * implementation simply returns the fragment of the first header.
+ */
+ public String onGetInitialFragment() {
+ return mHeaders.get(0).fragment;
+ }
+
+ /**
+ * Called when the activity needs its list of headers build. By
+ * implementing this and adding at least one item to the list, you
+ * will cause the activity to run in its modern fragment mode. Note
+ * that this function may not always be called; for example, if the
+ * activity has been asked to display a particular fragment without
+ * the header list, there is no need to build the headers.
+ *
+ * <p>Typical implementations will use {@link #loadHeadersFromResource}
+ * to fill in the list from a resource.
+ *
+ * @param target The list in which to place the headers.
+ */
+ public void onBuildHeaders(List<Header> target) {
+ }
+
+ /**
+ * Parse the given XML file as a header description, adding each
+ * parsed Header into the target list.
+ *
+ * @param resid The XML resource to load and parse.
+ * @param target The list in which the parsed headers should be placed.
+ */
+ public void loadHeadersFromResource(int resid, List<Header> target) {
+ XmlResourceParser parser = null;
+ try {
+ parser = getResources().getXml(resid);
+ AttributeSet attrs = Xml.asAttributeSet(parser);
+
+ int type;
+ while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+ && type != XmlPullParser.START_TAG) {
+ }
+
+ String nodeName = parser.getName();
+ if (!"PreferenceHeaders".equals(nodeName)) {
+ throw new RuntimeException(
+ "XML document must start with <PreferenceHeaders> tag; found"
+ + nodeName + " at " + parser.getPositionDescription());
+ }
+
+ int outerDepth = parser.getDepth();
+ while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ nodeName = parser.getName();
+ if ("Header".equals(nodeName)) {
+ Header header = new Header();
+
+ TypedArray sa = getResources().obtainAttributes(attrs,
+ com.android.internal.R.styleable.PreferenceHeader);
+ header.title = sa.getText(
+ com.android.internal.R.styleable.PreferenceHeader_title);
+ header.summary = sa.getText(
+ com.android.internal.R.styleable.PreferenceHeader_summary);
+ header.iconRes = sa.getResourceId(
+ com.android.internal.R.styleable.PreferenceHeader_icon, 0);
+ header.fragment = sa.getString(
+ com.android.internal.R.styleable.PreferenceHeader_fragment);
+ sa.recycle();
+
+ target.add(header);
+
+ XmlUtils.skipCurrentTag(parser);
+ } else {
+ XmlUtils.skipCurrentTag(parser);
+ }
+ }
+
+ } catch (XmlPullParserException e) {
+ throw new RuntimeException("Error parsing headers", e);
+ } catch (IOException e) {
+ throw new RuntimeException("Error parsing headers", e);
+ } finally {
+ if (parser != null) parser.close();
+ }
- mPreferenceManager = onCreatePreferenceManager();
- getListView().setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
}
@Override
protected void onStop() {
super.onStop();
- mPreferenceManager.dispatchActivityStop();
+ if (mPreferenceManager != null) {
+ mPreferenceManager.dispatchActivityStop();
+ }
}
@Override
protected void onDestroy() {
super.onDestroy();
- mPreferenceManager.dispatchActivityDestroy();
+
+ if (mPreferenceManager != null) {
+ mPreferenceManager.dispatchActivityDestroy();
+ }
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
- final PreferenceScreen preferenceScreen = getPreferenceScreen();
- if (preferenceScreen != null) {
- Bundle container = new Bundle();
- preferenceScreen.saveHierarchyState(container);
- outState.putBundle(PREFERENCES_TAG, container);
+ if (mPreferenceManager != null) {
+ final PreferenceScreen preferenceScreen = getPreferenceScreen();
+ if (preferenceScreen != null) {
+ Bundle container = new Bundle();
+ preferenceScreen.saveHierarchyState(container);
+ outState.putBundle(PREFERENCES_TAG, container);
+ }
}
}
@Override
protected void onRestoreInstanceState(Bundle state) {
- Bundle container = state.getBundle(PREFERENCES_TAG);
- if (container != null) {
- final PreferenceScreen preferenceScreen = getPreferenceScreen();
- if (preferenceScreen != null) {
- preferenceScreen.restoreHierarchyState(container);
- mSavedInstanceState = state;
- return;
+ if (mPreferenceManager != null) {
+ Bundle container = state.getBundle(PREFERENCES_TAG);
+ if (container != null) {
+ final PreferenceScreen preferenceScreen = getPreferenceScreen();
+ if (preferenceScreen != null) {
+ preferenceScreen.restoreHierarchyState(container);
+ mSavedInstanceState = state;
+ return;
+ }
}
}
@@ -214,13 +489,76 @@ public abstract class PreferenceActivity extends ListActivity implements
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
- mPreferenceManager.dispatchActivityResult(requestCode, resultCode, data);
+ if (mPreferenceManager != null) {
+ mPreferenceManager.dispatchActivityResult(requestCode, resultCode, data);
+ }
}
@Override
public void onContentChanged() {
super.onContentChanged();
- postBindPreferences();
+
+ if (mPreferenceManager != null) {
+ postBindPreferences();
+ }
+ }
+
+ @Override
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ super.onListItemClick(l, v, position, id);
+
+ if (mAdapter != null) {
+ onHeaderClick(mHeaders.get(position), position);
+ }
+ }
+
+ /**
+ * Called when the user selects an item in the header list. The default
+ * implementation will call either {@link #startWithFragment(String)}
+ * or {@link #switchToHeader(String)} as appropriate.
+ *
+ * @param header The header that was selected.
+ * @param position The header's position in the list.
+ */
+ public void onHeaderClick(Header header, int position) {
+ if (mSinglePane) {
+ startWithFragment(header.fragment);
+ } else {
+ switchToHeader(header.fragment);
+ }
+ }
+
+ /**
+ * Start a new instance of this activity, showing only the given
+ * preference fragment. When launched in this mode, the header list
+ * will be hidden and the given preference fragment will be instantiated
+ * and fill the entire activity.
+ *
+ * @param fragmentName The name of the fragment to display.
+ */
+ public void startWithFragment(String fragmentName) {
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setClass(this, getClass());
+ intent.putExtra(EXTRA_PREFS_SHOW_FRAGMENT, fragmentName);
+ intent.putExtra(EXTRA_PREFS_NO_HEADERS, true);
+ startActivity(intent);
+ }
+
+ /**
+ * When in two-pane mode, switch the fragment pane to show the given
+ * preference fragment.
+ *
+ * @param fragmentName The name of the fragment to display.
+ */
+ public void switchToHeader(String fragmentName) {
+ Fragment f;
+ try {
+ f = Fragment.instantiate(this, fragmentName);
+ } catch (Exception e) {
+ Log.w(TAG, "Failure instantiating fragment " + fragmentName, e);
+ return;
+ }
+ openFragmentTransaction().replace(com.android.internal.R.id.prefs, f).commit();
}
/**
@@ -246,27 +584,24 @@ public abstract class PreferenceActivity extends ListActivity implements
}
/**
- * Creates the {@link PreferenceManager}.
- *
- * @return The {@link PreferenceManager} used by this activity.
- */
- private PreferenceManager onCreatePreferenceManager() {
- PreferenceManager preferenceManager = new PreferenceManager(this, FIRST_REQUEST_CODE);
- preferenceManager.setOnPreferenceTreeClickListener(this);
- return preferenceManager;
- }
-
- /**
* Returns the {@link PreferenceManager} used by this activity.
* @return The {@link PreferenceManager}.
+ *
+ * @deprecated This function is not relevant for a modern fragment-based
+ * PreferenceActivity.
*/
+ @Deprecated
public PreferenceManager getPreferenceManager() {
return mPreferenceManager;
}
private void requirePreferenceManager() {
if (mPreferenceManager == null) {
- throw new RuntimeException("This should be called after super.onCreate.");
+ if (mAdapter == null) {
+ throw new RuntimeException("This should be called after super.onCreate.");
+ }
+ throw new RuntimeException(
+ "Modern two-pane PreferenceActivity requires use of a PreferenceFragment");
}
}
@@ -274,8 +609,14 @@ public abstract class PreferenceActivity extends ListActivity implements
* Sets the root of the preference hierarchy that this activity is showing.
*
* @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy.
+ *
+ * @deprecated This function is not relevant for a modern fragment-based
+ * PreferenceActivity.
*/
+ @Deprecated
public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
+ requirePreferenceManager();
+
if (mPreferenceManager.setPreferences(preferenceScreen) && preferenceScreen != null) {
postBindPreferences();
CharSequence title = getPreferenceScreen().getTitle();
@@ -291,16 +632,27 @@ public abstract class PreferenceActivity extends ListActivity implements
*
* @return The {@link PreferenceScreen} that is the root of the preference
* hierarchy.
+ *
+ * @deprecated This function is not relevant for a modern fragment-based
+ * PreferenceActivity.
*/
+ @Deprecated
public PreferenceScreen getPreferenceScreen() {
- return mPreferenceManager.getPreferenceScreen();
+ if (mPreferenceManager != null) {
+ return mPreferenceManager.getPreferenceScreen();
+ }
+ return null;
}
/**
* Adds preferences from activities that match the given {@link Intent}.
*
* @param intent The {@link Intent} to query activities.
+ *
+ * @deprecated This function is not relevant for a modern fragment-based
+ * PreferenceActivity.
*/
+ @Deprecated
public void addPreferencesFromIntent(Intent intent) {
requirePreferenceManager();
@@ -312,7 +664,11 @@ public abstract class PreferenceActivity extends ListActivity implements
* preference hierarchy.
*
* @param preferencesResId The XML resource ID to inflate.
+ *
+ * @deprecated This function is not relevant for a modern fragment-based
+ * PreferenceActivity.
*/
+ @Deprecated
public void addPreferencesFromResource(int preferencesResId) {
requirePreferenceManager();
@@ -322,7 +678,11 @@ public abstract class PreferenceActivity extends ListActivity implements
/**
* {@inheritDoc}
+ *
+ * @deprecated This function is not relevant for a modern fragment-based
+ * PreferenceActivity.
*/
+ @Deprecated
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
return false;
}
@@ -333,7 +693,11 @@ public abstract class PreferenceActivity extends ListActivity implements
* @param key The key of the preference to retrieve.
* @return The {@link Preference} with the key, or null.
* @see PreferenceGroup#findPreference(CharSequence)
+ *
+ * @deprecated This function is not relevant for a modern fragment-based
+ * PreferenceActivity.
*/
+ @Deprecated
public Preference findPreference(CharSequence key) {
if (mPreferenceManager == null) {
diff --git a/core/java/android/preference/PreferenceFragment.java b/core/java/android/preference/PreferenceFragment.java
index f85bc9e..ac61574 100644
--- a/core/java/android/preference/PreferenceFragment.java
+++ b/core/java/android/preference/PreferenceFragment.java
@@ -37,6 +37,17 @@ import android.widget.ListView;
* {@link PreferenceManager#getDefaultSharedPreferences(android.content.Context)}
* with a context in the same package as this fragment.
* <p>
+ * Furthermore, the preferences shown will follow the visual style of system
+ * preferences. It is easy to create a hierarchy of preferences (that can be
+ * shown on multiple screens) via XML. For these reasons, it is recommended to
+ * use this fragment (as a superclass) to deal with preferences in applications.
+ * <p>
+ * A {@link PreferenceScreen} object should be at the top of the preference
+ * hierarchy. Furthermore, subsequent {@link PreferenceScreen} in the hierarchy
+ * denote a screen break--that is the preferences contained within subsequent
+ * {@link PreferenceScreen} should be shown on another screen. The preference
+ * framework handles showing these other screens from the preference hierarchy.
+ * <p>
* The preference hierarchy can be formed in multiple ways:
* <li> From an XML file specifying the hierarchy
* <li> From different {@link Activity Activities} that each specify its own
@@ -61,24 +72,21 @@ import android.widget.ListView;
* As a convenience, this fragment implements a click listener for any
* preference in the current hierarchy, see
* {@link #onPreferenceTreeClick(PreferenceScreen, Preference)}.
- * <p>
- * See {@link PreferenceActivity} for more details.
*
* <a name="SampleCode"></a>
* <h3>Sample Code</h3>
*
- * <p>The following sample code shows the use if a PreferenceFragment to
- * embed preferences in a larger activity and switch between them. The content
- * layout of the activity is:</p>
+ * <p>The following sample code shows a simple preference fragment that is
+ * populated from a resource. The resource it loads is:</p>
*
- * {@sample development/samples/ApiDemos/res/layout/fragment_preferences.xml layout}
+ * {@sample development/samples/ApiDemos/res/xml/preferences.xml preferences}
*
- * <p>The code using this layout consists of an activity and three fragments.
- * One of the fragments is a list of categories the user can select; the other
- * two are the different preference options for the categories.</p>
+ * <p>The fragment implementation itself simply populates the preferences
+ * when created. Note that the preferences framework takes care of loading
+ * the current values out of the app preferences and writing them when changed:</p>
*
- * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentPreferences.java
- * activity}
+ * {@sample development/samples/ApiDemos/src/com/example/android/apis/preference/FragmentPreferences.java
+ * fragment}
*
* @see Preference
* @see PreferenceScreen