summaryrefslogtreecommitdiffstats
path: root/core/java/android/preference
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2010-07-28 14:32:15 -0700
committerDianne Hackborn <hackbod@google.com>2010-07-28 16:06:58 -0700
commit42c2936f3c6e048caafb17eb9fe91fa4a33c8b86 (patch)
treedc53aedab5b9bd4868d6d1c7f0141a7b71fd62b1 /core/java/android/preference
parentdb4c6ccf224cd512690cc3dcfacccc8acfa71ffd (diff)
downloadframeworks_base-42c2936f3c6e048caafb17eb9fe91fa4a33c8b86.zip
frameworks_base-42c2936f3c6e048caafb17eb9fe91fa4a33c8b86.tar.gz
frameworks_base-42c2936f3c6e048caafb17eb9fe91fa4a33c8b86.tar.bz2
Add PreferenceFragment.
Change-Id: I9b87ec2c15822cca5b460a9a2d589fc24e21a789
Diffstat (limited to 'core/java/android/preference')
-rw-r--r--core/java/android/preference/PreferenceFragment.java309
1 files changed, 309 insertions, 0 deletions
diff --git a/core/java/android/preference/PreferenceFragment.java b/core/java/android/preference/PreferenceFragment.java
new file mode 100644
index 0000000..f85bc9e
--- /dev/null
+++ b/core/java/android/preference/PreferenceFragment.java
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.preference;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+
+/**
+ * Shows a hierarchy of {@link Preference} objects as
+ * lists. 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 fragment will use, call
+ * {@link PreferenceManager#getDefaultSharedPreferences(android.content.Context)}
+ * with a context in the same package as this fragment.
+ * <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 fragment.
+ * <p>
+ * To specify an object hierarchy rooted with {@link PreferenceScreen}, use
+ * {@link #setPreferenceScreen(PreferenceScreen)}.
+ * <p>
+ * 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>
+ *
+ * {@sample development/samples/ApiDemos/res/layout/fragment_preferences.xml layout}
+ *
+ * <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>
+ *
+ * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentPreferences.java
+ * activity}
+ *
+ * @see Preference
+ * @see PreferenceScreen
+ */
+public abstract class PreferenceFragment extends Fragment implements
+ PreferenceManager.OnPreferenceTreeClickListener {
+
+ private static final String PREFERENCES_TAG = "android:preferences";
+
+ private PreferenceManager mPreferenceManager;
+ private ListView mList;
+ private boolean mHavePrefs;
+ private boolean mInitDone;
+
+ /**
+ * The starting request code given out to preference framework.
+ */
+ private static final int FIRST_REQUEST_CODE = 100;
+
+ private static final int MSG_BIND_PREFERENCES = 0;
+ private Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+
+ case MSG_BIND_PREFERENCES:
+ bindPreferences();
+ break;
+ }
+ }
+ };
+
+ final private Runnable mRequestFocus = new Runnable() {
+ public void run() {
+ mList.focusableViewAvailable(mList);
+ }
+ };
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mPreferenceManager = new PreferenceManager(getActivity(), FIRST_REQUEST_CODE);
+ mPreferenceManager.setOnPreferenceTreeClickListener(this);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(com.android.internal.R.layout.preference_list_content,
+ container, false);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ getListView().setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
+
+ if (mHavePrefs) {
+ bindPreferences();
+ }
+
+ mInitDone = true;
+
+ if (savedInstanceState != null) {
+ Bundle container = savedInstanceState.getBundle(PREFERENCES_TAG);
+ if (container != null) {
+ final PreferenceScreen preferenceScreen = getPreferenceScreen();
+ if (preferenceScreen != null) {
+ preferenceScreen.restoreHierarchyState(container);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ mPreferenceManager.dispatchActivityStop();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mPreferenceManager.dispatchActivityDestroy();
+ }
+
+ @Override
+ public 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);
+ }
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+
+ mPreferenceManager.dispatchActivityResult(requestCode, resultCode, data);
+ }
+
+ /**
+ * Returns the {@link PreferenceManager} used by this fragment.
+ * @return The {@link PreferenceManager}.
+ */
+ public PreferenceManager getPreferenceManager() {
+ return mPreferenceManager;
+ }
+
+ /**
+ * Sets the root of the preference hierarchy that this fragment is showing.
+ *
+ * @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy.
+ */
+ public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
+ if (mPreferenceManager.setPreferences(preferenceScreen) && preferenceScreen != null) {
+ mHavePrefs = true;
+ if (mInitDone) {
+ postBindPreferences();
+ }
+ }
+ }
+
+ /**
+ * Gets the root of the preference hierarchy that this fragment is showing.
+ *
+ * @return The {@link PreferenceScreen} that is the root of the preference
+ * hierarchy.
+ */
+ public PreferenceScreen getPreferenceScreen() {
+ return mPreferenceManager.getPreferenceScreen();
+ }
+
+ /**
+ * Adds preferences from activities that match the given {@link Intent}.
+ *
+ * @param intent The {@link Intent} to query activities.
+ */
+ public void addPreferencesFromIntent(Intent intent) {
+ requirePreferenceManager();
+
+ setPreferenceScreen(mPreferenceManager.inflateFromIntent(intent, getPreferenceScreen()));
+ }
+
+ /**
+ * Inflates the given XML resource and adds the preference hierarchy to the current
+ * preference hierarchy.
+ *
+ * @param preferencesResId The XML resource ID to inflate.
+ */
+ public void addPreferencesFromResource(int preferencesResId) {
+ requirePreferenceManager();
+
+ setPreferenceScreen(mPreferenceManager.inflateFromResource(getActivity(),
+ preferencesResId, getPreferenceScreen()));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+ return false;
+ }
+
+ /**
+ * Finds a {@link Preference} based on its key.
+ *
+ * @param key The key of the preference to retrieve.
+ * @return The {@link Preference} with the key, or null.
+ * @see PreferenceGroup#findPreference(CharSequence)
+ */
+ public Preference findPreference(CharSequence key) {
+ if (mPreferenceManager == null) {
+ return null;
+ }
+ return mPreferenceManager.findPreference(key);
+ }
+
+ private void requirePreferenceManager() {
+ if (mPreferenceManager == null) {
+ throw new RuntimeException("This should be called after super.onCreate.");
+ }
+ }
+
+ private void postBindPreferences() {
+ if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) return;
+ mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget();
+ }
+
+ private void bindPreferences() {
+ final PreferenceScreen preferenceScreen = getPreferenceScreen();
+ if (preferenceScreen != null) {
+ preferenceScreen.bind(getListView());
+ }
+ }
+
+ private ListView getListView() {
+ ensureList();
+ return mList;
+ }
+
+ private void ensureList() {
+ if (mList != null) {
+ return;
+ }
+ View root = getView();
+ if (root == null) {
+ throw new IllegalStateException("Content view not yet created");
+ }
+ View rawListView = root.findViewById(android.R.id.list);
+ if (!(rawListView instanceof ListView)) {
+ throw new RuntimeException(
+ "Content has view with id attribute 'android.R.id.list' "
+ + "that is not a ListView class");
+ }
+ mList = (ListView)rawListView;
+ if (mList == null) {
+ throw new RuntimeException(
+ "Your content must have a ListView whose id attribute is " +
+ "'android.R.id.list'");
+ }
+ mHandler.post(mRequestFocus);
+ }
+}