PreferenceActivity.java revision b7a2e4772220c4b41df1260cedaf8912f4b07547
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.preference; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport com.android.internal.util.XmlUtils; 20b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 21b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport org.xmlpull.v1.XmlPullParser; 22b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport org.xmlpull.v1.XmlPullParserException; 23b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 24b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport android.app.Fragment; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.ListActivity; 26b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport android.content.Context; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 28b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport android.content.res.Configuration; 29b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport android.content.res.TypedArray; 30b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport android.content.res.XmlResourceParser; 31b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport android.graphics.drawable.Drawable; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 3519ea2e0d788810473136ceca46c1c28326daff5eFreeman Ngimport android.text.TextUtils; 36b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport android.util.AttributeSet; 37b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport android.util.Log; 38b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport android.util.Xml; 39b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport android.view.LayoutInflater; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View; 41b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport android.view.ViewGroup; 4219ea2e0d788810473136ceca46c1c28326daff5eFreeman Ngimport android.view.View.OnClickListener; 43b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport android.widget.ArrayAdapter; 4419ea2e0d788810473136ceca46c1c28326daff5eFreeman Ngimport android.widget.Button; 45b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport android.widget.ImageView; 46b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport android.widget.ListView; 47b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport android.widget.TextView; 48b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 49b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport java.io.IOException; 50b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport java.util.ArrayList; 51b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackbornimport java.util.List; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 54b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * This is the base class for an activity to show a hierarchy of preferences 55b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * to the user. Prior to {@link android.os.Build.VERSION_CODES#HONEYCOMB} 56b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * this class only allowed the display of a single set of preference; this 57b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * functionality should now be found in the new {@link PreferenceFragment} 58b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * class. If you are using PreferenceActivity in its old mode, the documentation 59b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * there applies to the deprecated APIs here. 60b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 61b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <p>This activity shows one or more headers of preferences, each of with 62b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * is associated with a {@link PreferenceFragment} to display the preferences 63b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * of that header. The actual layout and display of these associations can 64b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * however vary; currently there are two major approaches it may take: 65b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 66b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <ul> 67b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <li>On a small screen it may display only the headers as a single list 68b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * when first launched. Selecting one of the header items will re-launch 69b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * the activity with it only showing the PreferenceFragment of that header. 70b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <li>On a large screen in may display both the headers and current 71b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * PreferenceFragment together as panes. Selecting a header item switches 72b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * to showing the correct PreferenceFragment for that item. 73b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * </ul> 74b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 75b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <p>Subclasses of PreferenceActivity should implement 76b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * {@link #onBuildHeaders} to populate the header list with the desired 77b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * items. Doing this implicitly switches the class into its new "headers 78b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * + fragments" mode rather than the old style of just showing a single 79b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * preferences list. 80b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 81b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <a name="SampleCode"></a> 82b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <h3>Sample Code</h3> 83b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 84b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <p>The following sample code shows a simple preference activity that 85b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * has two different sets of preferences. The implementation, consisting 86b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * of the activity itself as well as its two preference fragments is:</p> 87b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 88b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * {@sample development/samples/ApiDemos/src/com/example/android/apis/preference/PreferenceWithHeaders.java 89b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * activity} 9019ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng * 91b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <p>The preference_headers resource describes the headers to be displayed 92b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * and the fragments associated with them. It is: 93b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 94b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * {@sample development/samples/ApiDemos/res/xml/preference_headers.xml headers} 95b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 96b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * <p>The first header is shown by Prefs1Fragment, which populates itself 97b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * from the following XML resource:</p> 98b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * 99b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * {@sample development/samples/ApiDemos/res/xml/fragmented_preferences.xml preferences} 100b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * 101b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * <p>Note that this XML resource contains a preference screen holding another 102b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * fragment, the Prefs1FragmentInner implemented here. This allows the user 103b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * to traverse down a hierarchy of preferences; pressing back will pop each 104b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * fragment off the stack to return to the previous preferences. 105b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * 106b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * <p>See {@link PreferenceFragment} for information on implementing the 107b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * fragments themselves. 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class PreferenceActivity extends ListActivity implements 110b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn PreferenceManager.OnPreferenceTreeClickListener, 111b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn PreferenceFragment.OnPreferenceStartFragmentCallback { 112b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn private static final String TAG = "PreferenceActivity"; 11319ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String PREFERENCES_TAG = "android:preferences"; 11519ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 116b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn /** 117b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * When starting this activity, the invoking Intent can contain this extra 118b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * string to specify which fragment should be initially displayed. 119b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn */ 120b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn public static final String EXTRA_SHOW_FRAGMENT = ":android:show_fragment"; 121b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 122b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn /** 123b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * When starting this activity and using {@link #EXTRA_SHOW_FRAGMENT}, 124b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * this extra can also be specify to supply a Bundle of arguments to pass 125b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * to that fragment when it is instantiated during the initial creation 126b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * of PreferenceActivity. 127b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn */ 128b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn public static final String EXTRA_SHOW_FRAGMENT_ARGUMENTS = ":android:show_fragment_args"; 129b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn 130b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn /** 131b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * When starting this activity, the invoking Intent can contain this extra 132b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * boolean that the header list should not be displayed. This is most often 133b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * used in conjunction with {@link #EXTRA_SHOW_FRAGMENT} to launch 134b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * the activity to display a specific fragment that the user has navigated 135b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * to. 136b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn */ 137b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn public static final String EXTRA_NO_HEADERS = ":android:no_headers"; 138b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 139b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn private static final String BACK_STACK_PREFS = ":android:prefs"; 140b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn 14119ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng // extras that allow any preference activity to be launched as part of a wizard 14219ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 14319ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng // show Back and Next buttons? takes boolean parameter 14419ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng // Back will then return RESULT_CANCELED and Next RESULT_OK 14519ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng private static final String EXTRA_PREFS_SHOW_BUTTON_BAR = "extra_prefs_show_button_bar"; 14619ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 14709dbf1844016682ed461d080e32a43d0086e767dFreeman Ng // add a Skip button? 14809dbf1844016682ed461d080e32a43d0086e767dFreeman Ng private static final String EXTRA_PREFS_SHOW_SKIP = "extra_prefs_show_skip"; 14909dbf1844016682ed461d080e32a43d0086e767dFreeman Ng 15019ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng // specify custom text for the Back or Next buttons, or cause a button to not appear 15119ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng // at all by setting it to null 15219ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng private static final String EXTRA_PREFS_SET_NEXT_TEXT = "extra_prefs_set_next_text"; 15319ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng private static final String EXTRA_PREFS_SET_BACK_TEXT = "extra_prefs_set_back_text"; 15419ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 155b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn // --- State for new mode when showing a list of headers + prefs fragment 156b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 157b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn private final ArrayList<Header> mHeaders = new ArrayList<Header>(); 158b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 159b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn private HeaderAdapter mAdapter; 160b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 161b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn private View mPrefsContainer; 162b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 163b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn private boolean mSinglePane; 164b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 165b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn // --- State for old mode when showing a single preference list 16619ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private PreferenceManager mPreferenceManager; 16819ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 169e7fea45863afb10335cb7845aebcf2907d3c3e41Adam Powell private Bundle mSavedInstanceState; 170e7fea45863afb10335cb7845aebcf2907d3c3e41Adam Powell 171b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn // --- Common state 172b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 173b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn private Button mNextButton; 174b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The starting request code given out to preference framework. 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int FIRST_REQUEST_CODE = 100; 17919ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MSG_BIND_PREFERENCES = 0; 181b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn private static final int MSG_BUILD_HEADERS = 1; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Handler mHandler = new Handler() { 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (msg.what) { 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MSG_BIND_PREFERENCES: 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bindPreferences(); 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 189b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn case MSG_BUILD_HEADERS: 190b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn onBuildHeaders(mHeaders); 191b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn mAdapter.notifyDataSetChanged(); 192b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn break; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 197b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn private class HeaderViewHolder { 198b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn ImageView icon; 199b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn TextView title; 200b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn TextView summary; 201b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 202b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 203b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn private class HeaderAdapter extends ArrayAdapter<Header> { 204b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn private LayoutInflater mInflater; 205b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 206b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn public HeaderAdapter(Context context, List<Header> objects) { 207b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn super(context, 0, objects); 208b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 209b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 210b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 211b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn @Override 212b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn public View getView(int position, View convertView, ViewGroup parent) { 213b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn HeaderViewHolder holder; 214b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn View view; 215b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 216b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (convertView == null) { 217b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn view = mInflater.inflate(com.android.internal.R.layout.preference_list_item, 218b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn parent, false); 219b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn holder = new HeaderViewHolder(); 220b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn holder.icon = (ImageView)view.findViewById( 221b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn com.android.internal.R.id.icon); 222b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn holder.title = (TextView)view.findViewById( 223b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn com.android.internal.R.id.title); 224b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn holder.summary = (TextView)view.findViewById( 225b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn com.android.internal.R.id.summary); 226b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn view.setTag(holder); 227b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } else { 228b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn view = convertView; 229b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn holder = (HeaderViewHolder)view.getTag(); 230b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 231b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 232b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn Header header = getItem(position); 233b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (header.icon != null) holder.icon.setImageDrawable(header.icon); 234b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn else if (header.iconRes != 0) holder.icon.setImageResource(header.iconRes); 235b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (header.title != null) holder.title.setText(header.title); 236b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (header.summary != null) holder.summary.setText(header.summary); 237b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 238b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn return view; 239b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 240b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 241b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 242b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn /** 243b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * Description of a single Header item that the user can select. 244b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn */ 245b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn public static class Header { 246b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn /** 247b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * Title of the header that is shown to the user. 248b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * @attr ref android.R.styleable#PreferenceHeader_title 249b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn */ 250b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn CharSequence title; 251b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 252b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn /** 253b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * Optional summary describing what this header controls. 254b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * @attr ref android.R.styleable#PreferenceHeader_summary 255b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn */ 256b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn CharSequence summary; 257b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 258b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn /** 259b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * Optional icon resource to show for this header. 260b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * @attr ref android.R.styleable#PreferenceHeader_icon 261b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn */ 262b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn int iconRes; 263b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 264b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn /** 265b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * Optional icon drawable to show for this header. (If this is non-null, 266b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * the iconRes will be ignored.) 267b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn */ 268b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn Drawable icon; 269b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 270b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn /** 271b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * Full class name of the fragment to display when this header is 272b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * selected. 273b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn * @attr ref android.R.styleable#PreferenceHeader_fragment 274b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn */ 275b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn String fragment; 276b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn 277b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn /** 278b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * Optional arguments to supply to the fragment when it is 279b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * instantiated. 280b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn */ 281b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn Bundle fragmentArguments; 282b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 283b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onCreate(Bundle savedInstanceState) { 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onCreate(savedInstanceState); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setContentView(com.android.internal.R.layout.preference_list_content); 28919ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 290b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn mPrefsContainer = findViewById(com.android.internal.R.id.prefs); 291b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn boolean hidingHeaders = onIsHidingHeaders(); 292b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn mSinglePane = hidingHeaders || !onIsMultiPane(); 293b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn String initialFragment = getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT); 294b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn Bundle initialArguments = getIntent().getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS); 295b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 296b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (initialFragment != null && mSinglePane) { 297b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn // If we are just showing a fragment, we want to run in 298b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn // new fragment mode, but don't need to compute and show 299b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn // the headers. 300b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn getListView().setVisibility(View.GONE); 301b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn mPrefsContainer.setVisibility(View.VISIBLE); 302b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn switchToHeader(initialFragment, initialArguments); 303b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 304b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } else { 305b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn // We need to try to build the headers. 306b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn onBuildHeaders(mHeaders); 307b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 308b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn // If there are headers, then at this point we need to show 309b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn // them and, depending on the screen, we may also show in-line 310b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn // the currently selected preference fragment. 311b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (mHeaders.size() > 0) { 312b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn mAdapter = new HeaderAdapter(this, mHeaders); 313b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn setListAdapter(mAdapter); 314b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (!mSinglePane) { 315b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn mPrefsContainer.setVisibility(View.VISIBLE); 316b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn if (initialFragment != null) { 317b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn Header h = onGetInitialHeader(); 318b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn initialFragment = h.fragment; 319b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn initialArguments = h.fragmentArguments; 320b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn } 321b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn switchToHeader(initialFragment, initialArguments); 322b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 323b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 324b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn // If there are no headers, we are in the old "just show a screen 325b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn // of preferences" mode. 326b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } else { 327b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn mPreferenceManager = new PreferenceManager(this, FIRST_REQUEST_CODE); 328b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn mPreferenceManager.setOnPreferenceTreeClickListener(this); 329b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 330b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 331b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 332b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn getListView().setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); 333b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 33419ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng // see if we should show Back/Next buttons 33519ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng Intent intent = getIntent(); 33619ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false)) { 33719ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 33819ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng findViewById(com.android.internal.R.id.button_bar).setVisibility(View.VISIBLE); 33919ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 34019ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng Button backButton = (Button)findViewById(com.android.internal.R.id.back_button); 34119ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng backButton.setOnClickListener(new OnClickListener() { 34219ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng public void onClick(View v) { 34319ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng setResult(RESULT_CANCELED); 34419ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng finish(); 34519ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng } 34619ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng }); 34709dbf1844016682ed461d080e32a43d0086e767dFreeman Ng Button skipButton = (Button)findViewById(com.android.internal.R.id.skip_button); 34809dbf1844016682ed461d080e32a43d0086e767dFreeman Ng skipButton.setOnClickListener(new OnClickListener() { 34909dbf1844016682ed461d080e32a43d0086e767dFreeman Ng public void onClick(View v) { 35009dbf1844016682ed461d080e32a43d0086e767dFreeman Ng setResult(RESULT_OK); 35109dbf1844016682ed461d080e32a43d0086e767dFreeman Ng finish(); 35209dbf1844016682ed461d080e32a43d0086e767dFreeman Ng } 35309dbf1844016682ed461d080e32a43d0086e767dFreeman Ng }); 35419ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng mNextButton = (Button)findViewById(com.android.internal.R.id.next_button); 35519ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng mNextButton.setOnClickListener(new OnClickListener() { 35619ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng public void onClick(View v) { 35719ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng setResult(RESULT_OK); 35819ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng finish(); 35919ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng } 36019ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng }); 36119ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 36219ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng // set our various button parameters 36319ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng if (intent.hasExtra(EXTRA_PREFS_SET_NEXT_TEXT)) { 36419ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_NEXT_TEXT); 36519ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng if (TextUtils.isEmpty(buttonText)) { 36619ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng mNextButton.setVisibility(View.GONE); 36719ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng } 36819ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng else { 36919ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng mNextButton.setText(buttonText); 37019ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng } 37119ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng } 37219ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng if (intent.hasExtra(EXTRA_PREFS_SET_BACK_TEXT)) { 37319ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_BACK_TEXT); 37419ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng if (TextUtils.isEmpty(buttonText)) { 37519ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng backButton.setVisibility(View.GONE); 37619ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng } 37719ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng else { 37819ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng backButton.setText(buttonText); 37919ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng } 38019ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng } 38109dbf1844016682ed461d080e32a43d0086e767dFreeman Ng if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_SKIP, false)) { 38209dbf1844016682ed461d080e32a43d0086e767dFreeman Ng skipButton.setVisibility(View.VISIBLE); 38309dbf1844016682ed461d080e32a43d0086e767dFreeman Ng } 38419ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng } 385b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 386b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 387b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn /** 388b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * Called to determine if the activity should run in multi-pane mode. 389b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * The default implementation returns true if the screen is large 390b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * enough. 391b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn */ 392b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn public boolean onIsMultiPane() { 393b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn Configuration config = getResources().getConfiguration(); 394b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if ((config.screenLayout&Configuration.SCREENLAYOUT_SIZE_MASK) 395b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn == Configuration.SCREENLAYOUT_SIZE_XLARGE 396b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn && config.orientation == Configuration.ORIENTATION_LANDSCAPE) { 397b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn return true; 398b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 399b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn return false; 400b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 401b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 402b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn /** 403b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * Called to determine whether the header list should be hidden. The 404b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * default implementation hides the list if the activity is being re-launched 405b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * when not in multi-pane mode. 406b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn */ 407b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn public boolean onIsHidingHeaders() { 408b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn return getIntent().getBooleanExtra(EXTRA_NO_HEADERS, false); 409b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 410b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 411b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn /** 412b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * Called to determine the initial header to be shown. The default 413b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * implementation simply returns the fragment of the first header. Note 414b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * that the returned Header object does not actually need to exist in 415b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * your header list -- whatever its fragment is will simply be used to 416b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * show for the initial UI. 417b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn */ 418b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn public Header onGetInitialHeader() { 419b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn return mHeaders.get(0); 420b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 421b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 422b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn /** 423b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * Called when the activity needs its list of headers build. By 424b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * implementing this and adding at least one item to the list, you 425b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * will cause the activity to run in its modern fragment mode. Note 426b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * that this function may not always be called; for example, if the 427b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * activity has been asked to display a particular fragment without 428b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * the header list, there is no need to build the headers. 429b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 430b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <p>Typical implementations will use {@link #loadHeadersFromResource} 431b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * to fill in the list from a resource. 432b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 433b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * @param target The list in which to place the headers. 434b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn */ 435b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn public void onBuildHeaders(List<Header> target) { 436b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 437b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 438b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn /** 439b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * Call when you need to change the headers being displayed. Will result 440b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * in onBuildHeaders() later being called to retrieve the new list. 441b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn */ 442b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn public void invalidateHeaders() { 443b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn if (!mHandler.hasMessages(MSG_BUILD_HEADERS)) { 444b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn mHandler.sendEmptyMessage(MSG_BUILD_HEADERS); 445b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn } 446b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn } 447b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn 448b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn /** 449b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * Parse the given XML file as a header description, adding each 450b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * parsed Header into the target list. 451b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 452b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * @param resid The XML resource to load and parse. 453b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * @param target The list in which the parsed headers should be placed. 454b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn */ 455b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn public void loadHeadersFromResource(int resid, List<Header> target) { 456b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn XmlResourceParser parser = null; 457b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn try { 458b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn parser = getResources().getXml(resid); 459b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn AttributeSet attrs = Xml.asAttributeSet(parser); 460b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 461b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn int type; 462b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 463b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn && type != XmlPullParser.START_TAG) { 464b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 465b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 466b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn String nodeName = parser.getName(); 467b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (!"PreferenceHeaders".equals(nodeName)) { 468b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn throw new RuntimeException( 469b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn "XML document must start with <PreferenceHeaders> tag; found" 470b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn + nodeName + " at " + parser.getPositionDescription()); 471b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 472b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 473b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn int outerDepth = parser.getDepth(); 474b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 475b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 476b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 477b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn continue; 478b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 479b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 480b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn nodeName = parser.getName(); 481b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if ("Header".equals(nodeName)) { 482b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn Header header = new Header(); 483b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 484b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn TypedArray sa = getResources().obtainAttributes(attrs, 485b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn com.android.internal.R.styleable.PreferenceHeader); 486b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn header.title = sa.getText( 487b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn com.android.internal.R.styleable.PreferenceHeader_title); 488b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn header.summary = sa.getText( 489b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn com.android.internal.R.styleable.PreferenceHeader_summary); 490b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn header.iconRes = sa.getResourceId( 491b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn com.android.internal.R.styleable.PreferenceHeader_icon, 0); 492b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn header.fragment = sa.getString( 493b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn com.android.internal.R.styleable.PreferenceHeader_fragment); 494b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn sa.recycle(); 495b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 496b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn target.add(header); 497b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 498b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn XmlUtils.skipCurrentTag(parser); 499b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } else { 500b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn XmlUtils.skipCurrentTag(parser); 501b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 502b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 503b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 504b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } catch (XmlPullParserException e) { 505b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn throw new RuntimeException("Error parsing headers", e); 506b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } catch (IOException e) { 507b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn throw new RuntimeException("Error parsing headers", e); 508b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } finally { 509b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (parser != null) parser.close(); 510b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 51119ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onStop() { 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onStop(); 51719ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 518b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (mPreferenceManager != null) { 519b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn mPreferenceManager.dispatchActivityStop(); 520b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onDestroy() { 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onDestroy(); 526b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 527b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (mPreferenceManager != null) { 528b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn mPreferenceManager.dispatchActivityDestroy(); 529b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onSaveInstanceState(Bundle outState) { 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onSaveInstanceState(outState); 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 536b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (mPreferenceManager != null) { 537b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn final PreferenceScreen preferenceScreen = getPreferenceScreen(); 538b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (preferenceScreen != null) { 539b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn Bundle container = new Bundle(); 540b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn preferenceScreen.saveHierarchyState(container); 541b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn outState.putBundle(PREFERENCES_TAG, container); 542b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onRestoreInstanceState(Bundle state) { 548b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (mPreferenceManager != null) { 549b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn Bundle container = state.getBundle(PREFERENCES_TAG); 550b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (container != null) { 551b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn final PreferenceScreen preferenceScreen = getPreferenceScreen(); 552b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (preferenceScreen != null) { 553b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn preferenceScreen.restoreHierarchyState(container); 554b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn mSavedInstanceState = state; 555b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn return; 556b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 559e7fea45863afb10335cb7845aebcf2907d3c3e41Adam Powell 560e7fea45863afb10335cb7845aebcf2907d3c3e41Adam Powell // Only call this if we didn't save the instance state for later. 561e7fea45863afb10335cb7845aebcf2907d3c3e41Adam Powell // If we did save it, it will be restored when we bind the adapter. 562e7fea45863afb10335cb7845aebcf2907d3c3e41Adam Powell super.onRestoreInstanceState(state); 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onActivityResult(int requestCode, int resultCode, Intent data) { 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onActivityResult(requestCode, resultCode, data); 56819ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 569b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (mPreferenceManager != null) { 570b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn mPreferenceManager.dispatchActivityResult(requestCode, resultCode, data); 571b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onContentChanged() { 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onContentChanged(); 577b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 578b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (mPreferenceManager != null) { 579b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn postBindPreferences(); 580b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 581b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 582b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 583b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn @Override 584b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn protected void onListItemClick(ListView l, View v, int position, long id) { 585b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn super.onListItemClick(l, v, position, id); 586b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 587b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (mAdapter != null) { 588b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn onHeaderClick(mHeaders.get(position), position); 589b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 590b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 591b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 592b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn /** 593b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * Called when the user selects an item in the header list. The default 594b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * implementation will call either {@link #startWithFragment(String)} 595b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * or {@link #switchToHeader(String)} as appropriate. 596b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 597b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * @param header The header that was selected. 598b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * @param position The header's position in the list. 599b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn */ 600b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn public void onHeaderClick(Header header, int position) { 601b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (mSinglePane) { 602b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn startWithFragment(header.fragment, header.fragmentArguments); 603b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } else { 604b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn switchToHeader(header.fragment, header.fragmentArguments); 605b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 606b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 607b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 608b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn /** 609b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * Start a new instance of this activity, showing only the given 610b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * preference fragment. When launched in this mode, the header list 611b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * will be hidden and the given preference fragment will be instantiated 612b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * and fill the entire activity. 613b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 614b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * @param fragmentName The name of the fragment to display. 615b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * @param args Optional arguments to supply to the fragment. 616b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn */ 617b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn public void startWithFragment(String fragmentName, Bundle args) { 618b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn Intent intent = new Intent(Intent.ACTION_MAIN); 619b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn intent.setClass(this, getClass()); 620b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn intent.putExtra(EXTRA_SHOW_FRAGMENT, fragmentName); 621b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn intent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args); 622b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn intent.putExtra(EXTRA_NO_HEADERS, true); 623b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn startActivity(intent); 624b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 625b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 626b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn /** 627b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * When in two-pane mode, switch the fragment pane to show the given 628b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * preference fragment. 629b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 630b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * @param fragmentName The name of the fragment to display. 631b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn * @param args Optional arguments to supply to the fragment. 632b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn */ 633b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn public void switchToHeader(String fragmentName, Bundle args) { 634b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn popBackStack(BACK_STACK_PREFS, POP_BACK_STACK_INCLUSIVE); 635b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn 636b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn Fragment f = Fragment.instantiate(this, fragmentName, args); 637b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn openFragmentTransaction().replace(com.android.internal.R.id.prefs, f).commit(); 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 640b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn @Override 641b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) { 642b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn Fragment f = Fragment.instantiate(this, pref.getFragment()); 643b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn openFragmentTransaction().replace(com.android.internal.R.id.prefs, f) 644b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn .addToBackStack(BACK_STACK_PREFS).commit(); 645b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn return true; 646b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn } 647b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Posts a message to bind the preferences to the list view. 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Binding late is preferred as any custom preference types created in 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #onCreate(Bundle)} are able to have their views recycled. 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void postBindPreferences() { 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) return; 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget(); 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 65819ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void bindPreferences() { 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final PreferenceScreen preferenceScreen = getPreferenceScreen(); 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (preferenceScreen != null) { 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project preferenceScreen.bind(getListView()); 663e7fea45863afb10335cb7845aebcf2907d3c3e41Adam Powell if (mSavedInstanceState != null) { 664e7fea45863afb10335cb7845aebcf2907d3c3e41Adam Powell super.onRestoreInstanceState(mSavedInstanceState); 665e7fea45863afb10335cb7845aebcf2907d3c3e41Adam Powell mSavedInstanceState = null; 666e7fea45863afb10335cb7845aebcf2907d3c3e41Adam Powell } 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 66919ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the {@link PreferenceManager} used by this activity. 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The {@link PreferenceManager}. 673b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 674b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * @deprecated This function is not relevant for a modern fragment-based 675b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * PreferenceActivity. 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 677b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn @Deprecated 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PreferenceManager getPreferenceManager() { 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPreferenceManager; 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 68119ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void requirePreferenceManager() { 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPreferenceManager == null) { 684b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (mAdapter == null) { 685b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn throw new RuntimeException("This should be called after super.onCreate."); 686b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 687b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn throw new RuntimeException( 688b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn "Modern two-pane PreferenceActivity requires use of a PreferenceFragment"); 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the root of the preference hierarchy that this activity is showing. 69419ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng * 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy. 696b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 697b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * @deprecated This function is not relevant for a modern fragment-based 698b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * PreferenceActivity. 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 700b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn @Deprecated 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setPreferenceScreen(PreferenceScreen preferenceScreen) { 702b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn requirePreferenceManager(); 703b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPreferenceManager.setPreferences(preferenceScreen) && preferenceScreen != null) { 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project postBindPreferences(); 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CharSequence title = getPreferenceScreen().getTitle(); 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Set the title of the activity 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (title != null) { 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setTitle(title); 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 71319ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Gets the root of the preference hierarchy that this activity is showing. 71619ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng * 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The {@link PreferenceScreen} that is the root of the preference 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * hierarchy. 719b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 720b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * @deprecated This function is not relevant for a modern fragment-based 721b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * PreferenceActivity. 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 723b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn @Deprecated 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PreferenceScreen getPreferenceScreen() { 725b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn if (mPreferenceManager != null) { 726b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn return mPreferenceManager.getPreferenceScreen(); 727b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn } 728b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn return null; 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 73019ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Adds preferences from activities that match the given {@link Intent}. 73319ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng * 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param intent The {@link Intent} to query activities. 735b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 736b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * @deprecated This function is not relevant for a modern fragment-based 737b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * PreferenceActivity. 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 739b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn @Deprecated 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addPreferencesFromIntent(Intent intent) { 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requirePreferenceManager(); 74219ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setPreferenceScreen(mPreferenceManager.inflateFromIntent(intent, getPreferenceScreen())); 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 74519ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inflates the given XML resource and adds the preference hierarchy to the current 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * preference hierarchy. 74919ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng * 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param preferencesResId The XML resource ID to inflate. 751b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 752b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * @deprecated This function is not relevant for a modern fragment-based 753b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * PreferenceActivity. 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 755b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn @Deprecated 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addPreferencesFromResource(int preferencesResId) { 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requirePreferenceManager(); 75819ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setPreferenceScreen(mPreferenceManager.inflateFromResource(this, preferencesResId, 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getPreferenceScreen())); 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 765b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 766b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * @deprecated This function is not relevant for a modern fragment-based 767b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * PreferenceActivity. 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 769b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn @Deprecated 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 77319ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Finds a {@link Preference} based on its key. 77619ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng * 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param key The key of the preference to retrieve. 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The {@link Preference} with the key, or null. 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see PreferenceGroup#findPreference(CharSequence) 780b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * 781b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * @deprecated This function is not relevant for a modern fragment-based 782b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * PreferenceActivity. 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 784b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn @Deprecated 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Preference findPreference(CharSequence key) { 78619ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPreferenceManager == null) { 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 79019ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPreferenceManager.findPreference(key); 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onNewIntent(Intent intent) { 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPreferenceManager != null) { 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPreferenceManager.dispatchNewIntent(intent); 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 80019ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng 80119ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng // give subclasses access to the Next button 80219ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng /** @hide */ 80319ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng protected boolean hasNextButton() { 80419ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng return mNextButton != null; 80519ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng } 80619ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng /** @hide */ 80719ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng protected Button getNextButton() { 80819ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng return mNextButton; 80919ea2e0d788810473136ceca46c1c28326daff5eFreeman Ng } 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 811