142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn/* 242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * Copyright (C) 2010 The Android Open Source Project 342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * 442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * you may not use this file except in compliance with the License. 642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * You may obtain a copy of the License at 742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * 842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * 1042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 1142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 1242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * See the License for the specific language governing permissions and 1442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * limitations under the License. 1542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn */ 1642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 1742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornpackage android.preference; 1842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 1942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.app.Activity; 2042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.app.Fragment; 2142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.content.Intent; 2242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.content.SharedPreferences; 2342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.os.Bundle; 2442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.os.Handler; 2542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.os.Message; 26014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reckimport android.view.KeyEvent; 2742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.view.LayoutInflater; 2842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.view.View; 2942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.view.ViewGroup; 30014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reckimport android.view.View.OnKeyListener; 3142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.widget.ListView; 3242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 3342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn/** 3442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * Shows a hierarchy of {@link Preference} objects as 3542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * lists. These preferences will 3642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * automatically save to {@link SharedPreferences} as the user interacts with 3742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * them. To retrieve an instance of {@link SharedPreferences} that the 3842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * preference hierarchy in this fragment will use, call 3942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * {@link PreferenceManager#getDefaultSharedPreferences(android.content.Context)} 4042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * with a context in the same package as this fragment. 4142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <p> 42b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * Furthermore, the preferences shown will follow the visual style of system 43b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * preferences. It is easy to create a hierarchy of preferences (that can be 44b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * shown on multiple screens) via XML. For these reasons, it is recommended to 45b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * use this fragment (as a superclass) to deal with preferences in applications. 46b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <p> 47b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * A {@link PreferenceScreen} object should be at the top of the preference 48b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * hierarchy. Furthermore, subsequent {@link PreferenceScreen} in the hierarchy 49b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * denote a screen break--that is the preferences contained within subsequent 50b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * {@link PreferenceScreen} should be shown on another screen. The preference 51b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * framework handles showing these other screens from the preference hierarchy. 52b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <p> 5342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * The preference hierarchy can be formed in multiple ways: 5442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <li> From an XML file specifying the hierarchy 5542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <li> From different {@link Activity Activities} that each specify its own 5642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * preferences in an XML file via {@link Activity} meta-data 5742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <li> From an object hierarchy rooted with {@link PreferenceScreen} 5842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <p> 5942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * To inflate from XML, use the {@link #addPreferencesFromResource(int)}. The 6042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * root element should be a {@link PreferenceScreen}. Subsequent elements can point 6142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * to actual {@link Preference} subclasses. As mentioned above, subsequent 6242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * {@link PreferenceScreen} in the hierarchy will result in the screen break. 6342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <p> 6442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * To specify an {@link Intent} to query {@link Activity Activities} that each 6542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * have preferences, use {@link #addPreferencesFromIntent}. Each 6642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * {@link Activity} can specify meta-data in the manifest (via the key 6742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * {@link PreferenceManager#METADATA_KEY_PREFERENCES}) that points to an XML 6842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * resource. These XML resources will be inflated into a single preference 6942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * hierarchy and shown by this fragment. 7042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <p> 7142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * To specify an object hierarchy rooted with {@link PreferenceScreen}, use 7242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * {@link #setPreferenceScreen(PreferenceScreen)}. 7342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <p> 7442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * As a convenience, this fragment implements a click listener for any 7542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * preference in the current hierarchy, see 7642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * {@link #onPreferenceTreeClick(PreferenceScreen, Preference)}. 77cdd0c59a0108036895796dcb2bea69ff5eef26caScott Main * 78cdd0c59a0108036895796dcb2bea69ff5eef26caScott Main * <div class="special reference"> 79cdd0c59a0108036895796dcb2bea69ff5eef26caScott Main * <h3>Developer Guides</h3> 80cdd0c59a0108036895796dcb2bea69ff5eef26caScott Main * <p>For information about using {@code PreferenceFragment}, 81cdd0c59a0108036895796dcb2bea69ff5eef26caScott Main * read the <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a> 82cdd0c59a0108036895796dcb2bea69ff5eef26caScott Main * guide.</p> 83cdd0c59a0108036895796dcb2bea69ff5eef26caScott Main * </div> 8442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * 8542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <a name="SampleCode"></a> 8642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <h3>Sample Code</h3> 8742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * 88b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <p>The following sample code shows a simple preference fragment that is 89b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * populated from a resource. The resource it loads is:</p> 9042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * 91b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * {@sample development/samples/ApiDemos/res/xml/preferences.xml preferences} 9242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * 93b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <p>The fragment implementation itself simply populates the preferences 94b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * when created. Note that the preferences framework takes care of loading 95b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * the current values out of the app preferences and writing them when changed:</p> 9642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * 97b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * {@sample development/samples/ApiDemos/src/com/example/android/apis/preference/FragmentPreferences.java 98b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * fragment} 9942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * 10042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * @see Preference 10142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * @see PreferenceScreen 10242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn */ 10342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornpublic abstract class PreferenceFragment extends Fragment implements 10442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn PreferenceManager.OnPreferenceTreeClickListener { 10542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 10642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn private static final String PREFERENCES_TAG = "android:preferences"; 10742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 10842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn private PreferenceManager mPreferenceManager; 10942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn private ListView mList; 11042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn private boolean mHavePrefs; 11142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn private boolean mInitDone; 11242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 11342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn /** 11442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * The starting request code given out to preference framework. 11542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn */ 11642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn private static final int FIRST_REQUEST_CODE = 100; 11742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 1183e449ce00ed2d3b271e50bc7a52798f630973bf1Dianne Hackborn private static final int MSG_BIND_PREFERENCES = 1; 11942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn private Handler mHandler = new Handler() { 12042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn @Override 12142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn public void handleMessage(Message msg) { 12242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn switch (msg.what) { 12342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 12442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn case MSG_BIND_PREFERENCES: 12542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn bindPreferences(); 12642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn break; 12742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 12842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 12942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn }; 13042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 13142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn final private Runnable mRequestFocus = new Runnable() { 13242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn public void run() { 13342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn mList.focusableViewAvailable(mList); 13442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 13542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn }; 13642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 137b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn /** 138b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * Interface that PreferenceFragment's containing activity should 139b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * implement to be able to process preference items that wish to 140b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * switch to a new fragment. 141b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn */ 142b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn public interface OnPreferenceStartFragmentCallback { 143b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn /** 144b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * Called when the user has clicked on a Preference that has 145b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * a fragment class name associated with it. The implementation 146b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * to should instantiate and switch to an instance of the given 147b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * fragment. 148b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn */ 149b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref); 150b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn } 151b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn 15242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn @Override 15342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn public void onCreate(Bundle savedInstanceState) { 15442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn super.onCreate(savedInstanceState); 15542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn mPreferenceManager = new PreferenceManager(getActivity(), FIRST_REQUEST_CODE); 15682e7bc11342547d1480ef89208ed06943650e201Amith Yamasani mPreferenceManager.setFragment(this); 15742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 15842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 15942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn @Override 16042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn public View onCreateView(LayoutInflater inflater, ViewGroup container, 16142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn Bundle savedInstanceState) { 162405c1af75607fafdb1d6faf34e13e032e4934787Amith Yamasani return inflater.inflate(com.android.internal.R.layout.preference_list_fragment, container, 163405c1af75607fafdb1d6faf34e13e032e4934787Amith Yamasani false); 16442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 16542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 16642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn @Override 16742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn public void onActivityCreated(Bundle savedInstanceState) { 16842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn super.onActivityCreated(savedInstanceState); 16942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 17042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn if (mHavePrefs) { 17142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn bindPreferences(); 17242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 17342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 17442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn mInitDone = true; 17542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 17642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn if (savedInstanceState != null) { 17742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn Bundle container = savedInstanceState.getBundle(PREFERENCES_TAG); 17842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn if (container != null) { 17942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn final PreferenceScreen preferenceScreen = getPreferenceScreen(); 18042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn if (preferenceScreen != null) { 18142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn preferenceScreen.restoreHierarchyState(container); 18242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 18342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 18442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 18542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 18642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 18742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn @Override 188c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani public void onStart() { 189c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani super.onStart(); 190c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani mPreferenceManager.setOnPreferenceTreeClickListener(this); 191c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani } 192c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani 193c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani @Override 19442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn public void onStop() { 19542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn super.onStop(); 19642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn mPreferenceManager.dispatchActivityStop(); 197c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani mPreferenceManager.setOnPreferenceTreeClickListener(null); 19842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 19942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 20042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn @Override 201b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn public void onDestroyView() { 202b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn mList = null; 203b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn mHandler.removeCallbacks(mRequestFocus); 20481d860013c7eeb96a09574301485d3e405ce03bcAmith Yamasani mHandler.removeMessages(MSG_BIND_PREFERENCES); 205b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn super.onDestroyView(); 206b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn } 207b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn 208b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn @Override 20942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn public void onDestroy() { 21042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn super.onDestroy(); 21142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn mPreferenceManager.dispatchActivityDestroy(); 21242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 21342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 21442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn @Override 21542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn public void onSaveInstanceState(Bundle outState) { 21642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn super.onSaveInstanceState(outState); 21742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 21842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn final PreferenceScreen preferenceScreen = getPreferenceScreen(); 21942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn if (preferenceScreen != null) { 22042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn Bundle container = new Bundle(); 22142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn preferenceScreen.saveHierarchyState(container); 22242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn outState.putBundle(PREFERENCES_TAG, container); 22342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 22442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 22542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 22642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn @Override 22742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn public void onActivityResult(int requestCode, int resultCode, Intent data) { 22842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn super.onActivityResult(requestCode, resultCode, data); 22942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 23042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn mPreferenceManager.dispatchActivityResult(requestCode, resultCode, data); 23142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 23242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 23342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn /** 23442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * Returns the {@link PreferenceManager} used by this fragment. 23542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * @return The {@link PreferenceManager}. 23642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn */ 23742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn public PreferenceManager getPreferenceManager() { 23842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn return mPreferenceManager; 23942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 24042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 24142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn /** 24242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * Sets the root of the preference hierarchy that this fragment is showing. 24342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * 24442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy. 24542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn */ 24642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn public void setPreferenceScreen(PreferenceScreen preferenceScreen) { 24742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn if (mPreferenceManager.setPreferences(preferenceScreen) && preferenceScreen != null) { 24842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn mHavePrefs = true; 24942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn if (mInitDone) { 25042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn postBindPreferences(); 25142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 25242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 25342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 25442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 25542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn /** 25642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * Gets the root of the preference hierarchy that this fragment is showing. 25742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * 25842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * @return The {@link PreferenceScreen} that is the root of the preference 25942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * hierarchy. 26042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn */ 26142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn public PreferenceScreen getPreferenceScreen() { 26242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn return mPreferenceManager.getPreferenceScreen(); 26342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 26442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 26542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn /** 26642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * Adds preferences from activities that match the given {@link Intent}. 26742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * 26842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * @param intent The {@link Intent} to query activities. 26942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn */ 27042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn public void addPreferencesFromIntent(Intent intent) { 27142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn requirePreferenceManager(); 27242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 27342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn setPreferenceScreen(mPreferenceManager.inflateFromIntent(intent, getPreferenceScreen())); 27442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 27542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 27642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn /** 27742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * Inflates the given XML resource and adds the preference hierarchy to the current 27842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * preference hierarchy. 27942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * 28042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * @param preferencesResId The XML resource ID to inflate. 28142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn */ 28242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn public void addPreferencesFromResource(int preferencesResId) { 28342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn requirePreferenceManager(); 28442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 28542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn setPreferenceScreen(mPreferenceManager.inflateFromResource(getActivity(), 28642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn preferencesResId, getPreferenceScreen())); 28742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 28842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 28942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn /** 29042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * {@inheritDoc} 29142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn */ 292b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, 293b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn Preference preference) { 294b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn if (preference.getFragment() != null && 295b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn getActivity() instanceof OnPreferenceStartFragmentCallback) { 296b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn return ((OnPreferenceStartFragmentCallback)getActivity()).onPreferenceStartFragment( 297b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn this, preference); 298b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn } 29942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn return false; 30042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 30142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 30242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn /** 30342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * Finds a {@link Preference} based on its key. 30442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * 30542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * @param key The key of the preference to retrieve. 30642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * @return The {@link Preference} with the key, or null. 30742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * @see PreferenceGroup#findPreference(CharSequence) 30842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn */ 30942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn public Preference findPreference(CharSequence key) { 31042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn if (mPreferenceManager == null) { 31142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn return null; 31242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 31342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn return mPreferenceManager.findPreference(key); 31442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 31542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 31642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn private void requirePreferenceManager() { 31742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn if (mPreferenceManager == null) { 31842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn throw new RuntimeException("This should be called after super.onCreate."); 31942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 32042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 32142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 32242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn private void postBindPreferences() { 32342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) return; 32442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget(); 32542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 32642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 32742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn private void bindPreferences() { 32842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn final PreferenceScreen preferenceScreen = getPreferenceScreen(); 32942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn if (preferenceScreen != null) { 33042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn preferenceScreen.bind(getListView()); 33142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 33242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 33342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 3349ae5473eae5312575521d87ec0303ac91560cbedAmith Yamasani /** @hide */ 3359ae5473eae5312575521d87ec0303ac91560cbedAmith Yamasani public ListView getListView() { 33642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn ensureList(); 33742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn return mList; 33842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 33942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn 34042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn private void ensureList() { 34142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn if (mList != null) { 34242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn return; 34342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 34442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn View root = getView(); 34542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn if (root == null) { 34642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn throw new IllegalStateException("Content view not yet created"); 34742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 34842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn View rawListView = root.findViewById(android.R.id.list); 34942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn if (!(rawListView instanceof ListView)) { 35042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn throw new RuntimeException( 35142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn "Content has view with id attribute 'android.R.id.list' " 35242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn + "that is not a ListView class"); 35342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 35442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn mList = (ListView)rawListView; 35542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn if (mList == null) { 35642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn throw new RuntimeException( 35742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn "Your content must have a ListView whose id attribute is " + 35842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn "'android.R.id.list'"); 35942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 360014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck mList.setOnKeyListener(mListOnKeyListener); 36142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn mHandler.post(mRequestFocus); 36242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn } 363014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck 364014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck private OnKeyListener mListOnKeyListener = new OnKeyListener() { 365014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck 366014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck @Override 367014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck public boolean onKey(View v, int keyCode, KeyEvent event) { 368014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck Object selectedItem = mList.getSelectedItem(); 369014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck if (selectedItem instanceof Preference) { 370014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck View selectedView = mList.getSelectedView(); 371014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck return ((Preference)selectedItem).onKey( 372014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck selectedView, keyCode, event); 373014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck } 374014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck return false; 375014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck } 376014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck 377014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck }; 37842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn} 379