PreferenceActivity.java revision 327fbd2c8fa294b919475feb4c74a74ee1981e02
1518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian/* 2518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Copyright (C) 2007 The Android Open Source Project 3518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 4518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 5518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * you may not use this file except in compliance with the License. 6518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * You may obtain a copy of the License at 7518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 8518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 9518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 10518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Unless required by applicable law or agreed to in writing, software 11518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 12518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * See the License for the specific language governing permissions and 14518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * limitations under the License. 15518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 16518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennispackage android.preference; 181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 19518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport com.android.internal.util.XmlUtils; 20518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 21518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport org.xmlpull.v1.XmlPullParser; 22518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport org.xmlpull.v1.XmlPullParserException; 23518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 24518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.app.ActionBar; 25518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.app.Fragment; 26518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.app.FragmentBreadCrumbs; 27518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.app.FragmentManager; 28518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.app.FragmentTransaction; 29518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.app.ListActivity; 30518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.content.Context; 31518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.content.Intent; 32518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.content.res.Configuration; 337db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopianimport android.content.res.Resources; 34518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.content.res.TypedArray; 35518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.content.res.XmlResourceParser; 36518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.os.Bundle; 37518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.os.Handler; 38518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.os.Message; 39518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.os.Parcel; 401c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennisimport android.os.Parcelable; 41518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.text.TextUtils; 42518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.util.AttributeSet; 43518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.util.TypedValue; 440469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyimport android.util.Xml; 45518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.view.LayoutInflater; 46518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.view.View; 47518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.view.View.OnClickListener; 48518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.view.ViewGroup; 49518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.widget.AbsListView; 50518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.widget.ArrayAdapter; 51ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopianimport android.widget.Button; 52518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.widget.FrameLayout; 53518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.widget.ImageView; 54518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.widget.ListView; 55518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport android.widget.TextView; 56518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 57bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopianimport java.io.IOException; 58bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopianimport java.util.ArrayList; 59518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianimport java.util.List; 60518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 61518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian/** 62518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * This is the base class for an activity to show a hierarchy of preferences 63518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * to the user. Prior to {@link android.os.Build.VERSION_CODES#HONEYCOMB} 64518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * this class only allowed the display of a single set of preference; this 65518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * functionality should now be found in the new {@link PreferenceFragment} 66518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * class. If you are using PreferenceActivity in its old mode, the documentation 67518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * there applies to the deprecated APIs here. 68518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 69518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * <p>This activity shows one or more headers of preferences, each of with 70518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * is associated with a {@link PreferenceFragment} to display the preferences 71518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * of that header. The actual layout and display of these associations can 72518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * however vary; currently there are two major approaches it may take: 731c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang * 741c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang * <ul> 751c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang * <li>On a small screen it may display only the headers as a single list 761c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang * when first launched. Selecting one of the header items will re-launch 77518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * the activity with it only showing the PreferenceFragment of that header. 78518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * <li>On a large screen in may display both the headers and current 79518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * PreferenceFragment together as panes. Selecting a header item switches 80518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * to showing the correct PreferenceFragment for that item. 81518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * </ul> 82518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 83518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * <p>Subclasses of PreferenceActivity should implement 84518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * {@link #onBuildHeaders} to populate the header list with the desired 85518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * items. Doing this implicitly switches the class into its new "headers 86518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * + fragments" mode rather than the old style of just showing a single 87518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * preferences list. 88518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 89518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * <a name="SampleCode"></a> 90518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * <h3>Sample Code</h3> 91518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 92518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * <p>The following sample code shows a simple preference activity that 93518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * has two different sets of preferences. The implementation, consisting 94518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * of the activity itself as well as its two preference fragments is:</p> 95518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 96518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * {@sample development/samples/ApiDemos/src/com/example/android/apis/preference/PreferenceWithHeaders.java 97518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * activity} 98518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 99518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * <p>The preference_headers resource describes the headers to be displayed 100518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * and the fragments associated with them. It is: 101518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 102518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * {@sample development/samples/ApiDemos/res/xml/preference_headers.xml headers} 103518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 104518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * <p>The first header is shown by Prefs1Fragment, which populates itself 105518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * from the following XML resource:</p> 106518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 107518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * {@sample development/samples/ApiDemos/res/xml/fragmented_preferences.xml preferences} 108518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 109518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * <p>Note that this XML resource contains a preference screen holding another 110518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * fragment, the Prefs1FragmentInner implemented here. This allows the user 111518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * to traverse down a hierarchy of preferences; pressing back will pop each 112518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * fragment off the stack to return to the previous preferences. 113518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 114518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * <p>See {@link PreferenceFragment} for information on implementing the 115518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * fragments themselves. 116518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 117518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianpublic abstract class PreferenceActivity extends ListActivity implements 118518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian PreferenceManager.OnPreferenceTreeClickListener, 119518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian PreferenceFragment.OnPreferenceStartFragmentCallback { 120518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private static final String TAG = "PreferenceActivity"; 121518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 122518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // Constants for state save/restore 123518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private static final String HEADERS_TAG = ":android:headers"; 124518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private static final String CUR_HEADER_TAG = ":android:cur_header"; 125518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private static final String PREFERENCES_TAG = ":android:preferences"; 126518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 127518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 128518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * When starting this activity, the invoking Intent can contain this extra 129518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * string to specify which fragment should be initially displayed. 130518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 131518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public static final String EXTRA_SHOW_FRAGMENT = ":android:show_fragment"; 132518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 133518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 134518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * When starting this activity and using {@link #EXTRA_SHOW_FRAGMENT}, 135518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * this extra can also be specify to supply a Bundle of arguments to pass 136b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall * to that fragment when it is instantiated during the initial creation 137518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * of PreferenceActivity. 138518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 139518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public static final String EXTRA_SHOW_FRAGMENT_ARGUMENTS = ":android:show_fragment_args"; 140518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 141518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 142518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * When starting this activity, the invoking Intent can contain this extra 143518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * boolean that the header list should not be displayed. This is most often 144518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * used in conjunction with {@link #EXTRA_SHOW_FRAGMENT} to launch 145518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * the activity to display a specific fragment that the user has navigated 146518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * to. 147518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 148518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public static final String EXTRA_NO_HEADERS = ":android:no_headers"; 149518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 150518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private static final String BACK_STACK_PREFS = ":android:prefs"; 151518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 152b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall // extras that allow any preference activity to be launched as part of a wizard 153518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 154518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // show Back and Next buttons? takes boolean parameter 155518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // Back will then return RESULT_CANCELED and Next RESULT_OK 156518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private static final String EXTRA_PREFS_SHOW_BUTTON_BAR = "extra_prefs_show_button_bar"; 157518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 158518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // add a Skip button? 159518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private static final String EXTRA_PREFS_SHOW_SKIP = "extra_prefs_show_skip"; 160518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 161518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // specify custom text for the Back or Next buttons, or cause a button to not appear 162518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // at all by setting it to null 163518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private static final String EXTRA_PREFS_SET_NEXT_TEXT = "extra_prefs_set_next_text"; 164518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private static final String EXTRA_PREFS_SET_BACK_TEXT = "extra_prefs_set_back_text"; 165518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 166518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // --- State for new mode when showing a list of headers + prefs fragment 167518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 168518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private final ArrayList<Header> mHeaders = new ArrayList<Header>(); 169518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 170b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall private HeaderAdapter mAdapter; 171518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 172518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private FrameLayout mListFooter; 1737773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian 1747773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian private ViewGroup mPrefsContainer; 175518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 176518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private FragmentBreadCrumbs mFragmentBreadCrumbs; 1777773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian 1787773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian private boolean mSinglePane; 1797773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian 1807773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian private Header mCurHeader; 1817773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian 1827773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian // --- State for old mode when showing a single preference list 1837773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian 184518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private PreferenceManager mPreferenceManager; 1857773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian 1867773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian private Bundle mSavedInstanceState; 187518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 188518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // --- Common state 189518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 190518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private Button mNextButton; 191518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 192518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 193518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * The starting request code given out to preference framework. 194518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 195b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall private static final int FIRST_REQUEST_CODE = 100; 196518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 197518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private static final int MSG_BIND_PREFERENCES = 1; 198518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private static final int MSG_BUILD_HEADERS = 2; 199518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private Handler mHandler = new Handler() { 200518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian @Override 201518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public void handleMessage(Message msg) { 202518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian switch (msg.what) { 203518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case MSG_BIND_PREFERENCES: { 204518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian bindPreferences(); 205ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian } break; 206ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian case MSG_BUILD_HEADERS: { 2077773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian ArrayList<Header> oldHeaders = new ArrayList<Header>(mHeaders); 2087773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian mHeaders.clear(); 209518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian onBuildHeaders(mHeaders); 210518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (mAdapter != null) { 211518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mAdapter.notifyDataSetChanged(); 212518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 213518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Header header = onGetNewHeader(); 214518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (header != null && header.fragment != null) { 215518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Header mappedHeader = findBestMatchingHeader(header, oldHeaders); 216518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (mappedHeader == null || mCurHeader != mappedHeader) { 217518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian switchToHeader(header); 218b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } 219b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } else if (mCurHeader != null) { 220b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall Header mappedHeader = findBestMatchingHeader(mCurHeader, mHeaders); 221518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (mappedHeader != null) { 222518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian setSelectedHeader(mappedHeader); 2237773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian } 224518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 225518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } break; 226518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 227518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 228518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian }; 229518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 230518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private static class HeaderAdapter extends ArrayAdapter<Header> { 231518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private static class HeaderViewHolder { 232518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ImageView icon; 233518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian TextView title; 234518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian TextView summary; 235518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 236b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall 237b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall private LayoutInflater mInflater; 238b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall 239ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian public HeaderAdapter(Context context, List<Header> objects) { 240518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian super(context, 0, objects); 241518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 24281a63350527cafce6929309533c58586878f10b5Mathias Agopian } 243e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block 24481a63350527cafce6929309533c58586878f10b5Mathias Agopian @Override 24581a63350527cafce6929309533c58586878f10b5Mathias Agopian public View getView(int position, View convertView, ViewGroup parent) { 24681a63350527cafce6929309533c58586878f10b5Mathias Agopian HeaderViewHolder holder; 24781a63350527cafce6929309533c58586878f10b5Mathias Agopian View view; 248518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 249518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (convertView == null) { 2507773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian view = mInflater.inflate(com.android.internal.R.layout.preference_header_item, 251518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian parent, false); 252bee205fd58a27c10a0895de5339e76025d429d2bJamie Gennis holder = new HeaderViewHolder(); 253bee205fd58a27c10a0895de5339e76025d429d2bJamie Gennis holder.icon = (ImageView) view.findViewById(com.android.internal.R.id.icon); 254e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block holder.title = (TextView) view.findViewById(com.android.internal.R.id.title); 255bee205fd58a27c10a0895de5339e76025d429d2bJamie Gennis holder.summary = (TextView) view.findViewById(com.android.internal.R.id.summary); 25681a63350527cafce6929309533c58586878f10b5Mathias Agopian view.setTag(holder); 257bee205fd58a27c10a0895de5339e76025d429d2bJamie Gennis } else { 258bee205fd58a27c10a0895de5339e76025d429d2bJamie Gennis view = convertView; 259518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian holder = (HeaderViewHolder) view.getTag(); 260518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 261518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 26259769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis // All view fields must be updated every time, because the view may be recycled 26359769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis Header header = getItem(position); 26459769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis holder.icon.setImageResource(header.iconRes); 26559769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis holder.title.setText(header.getTitle(getContext().getResources())); 26659769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis CharSequence summary = header.getSummary(getContext().getResources()); 267518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (!TextUtils.isEmpty(summary)) { 2687773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian holder.summary.setVisibility(View.VISIBLE); 269518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian holder.summary.setText(summary); 270b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } else { 271b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall holder.summary.setVisibility(View.GONE); 272518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 273518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 27481a63350527cafce6929309533c58586878f10b5Mathias Agopian return view; 27581a63350527cafce6929309533c58586878f10b5Mathias Agopian } 27681a63350527cafce6929309533c58586878f10b5Mathias Agopian } 27781a63350527cafce6929309533c58586878f10b5Mathias Agopian 278518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 279518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Default value for {@link Header#id Header.id} indicating that no 280518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * identifier value is set. All other values (including those below -1) 281518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * are valid. 282518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 283518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public static final long HEADER_ID_UNDEFINED = -1; 284518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 285518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 286518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Description of a single Header item that the user can select. 287518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 288b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall public static final class Header implements Parcelable { 289b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall /** 290b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall * Identifier for this header, to correlate with a new list when 291518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * it is updated. The default value is 2927773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian * {@link PreferenceActivity#HEADER_ID_UNDEFINED}, meaning no id. 293518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @attr ref android.R.styleable#PreferenceHeader_id 294b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall */ 295b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall public long id = HEADER_ID_UNDEFINED; 296518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 297518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 298518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Resource ID of title of the header that is shown to the user. 299518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @attr ref android.R.styleable#PreferenceHeader_title 300518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 301518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public int titleRes; 302518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 303518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 304518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Title of the header that is shown to the user. 305518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @attr ref android.R.styleable#PreferenceHeader_title 306518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 307b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall public CharSequence title; 308b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall 309b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall /** 310518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Resource ID of optional summary describing what this header controls. 3117773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian * @attr ref android.R.styleable#PreferenceHeader_summary 312518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 313b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall public int summaryRes; 314b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall 315518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 316518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Optional summary describing what this header controls. 317518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @attr ref android.R.styleable#PreferenceHeader_summary 318518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 319518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public CharSequence summary; 320518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 321518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 322518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Resource ID of optional text to show as the title in the bread crumb. 323518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @attr ref android.R.styleable#PreferenceHeader_breadCrumbTitle 324518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 325b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall public int breadCrumbTitleRes; 326518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 327518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 328b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall * Optional text to show as the title in the bread crumb. 3295b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian * @attr ref android.R.styleable#PreferenceHeader_breadCrumbTitle 3305b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian */ 331518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public CharSequence breadCrumbTitle; 332518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 333ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian /** 334518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Resource ID of optional text to show as the short title in the bread crumb. 335518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @attr ref android.R.styleable#PreferenceHeader_breadCrumbShortTitle 336518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 337518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public int breadCrumbShortTitleRes; 338518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 339518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 340518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Optional text to show as the short title in the bread crumb. 341518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @attr ref android.R.styleable#PreferenceHeader_breadCrumbShortTitle 342518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 343518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public CharSequence breadCrumbShortTitle; 344518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 345b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall /** 346518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Optional icon resource to show for this header. 347518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @attr ref android.R.styleable#PreferenceHeader_icon 348b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall */ 3495b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian public int iconRes; 3505b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian 351518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 352518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Full class name of the fragment to display when this header is 3537773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian * selected. 3547773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian * @attr ref android.R.styleable#PreferenceHeader_fragment 355518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 356518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public String fragment; 357e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 3581c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis /** 359e8696a40e09b24b634214684d18526187b316a2fJamie Gennis * Optional arguments to supply to the fragment when it is 360e8696a40e09b24b634214684d18526187b316a2fJamie Gennis * instantiated. 361b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall */ 362e8696a40e09b24b634214684d18526187b316a2fJamie Gennis public Bundle fragmentArguments; 363e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 364e8696a40e09b24b634214684d18526187b316a2fJamie Gennis /** 365e8696a40e09b24b634214684d18526187b316a2fJamie Gennis * Intent to launch when the preference is selected. 366b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall */ 367e8696a40e09b24b634214684d18526187b316a2fJamie Gennis public Intent intent; 368e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 369e8696a40e09b24b634214684d18526187b316a2fJamie Gennis /** 370e8696a40e09b24b634214684d18526187b316a2fJamie Gennis * Optional additional data for use by subclasses of PreferenceActivity. 371e8696a40e09b24b634214684d18526187b316a2fJamie Gennis */ 372e8696a40e09b24b634214684d18526187b316a2fJamie Gennis public Bundle extras; 373e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 374e8696a40e09b24b634214684d18526187b316a2fJamie Gennis public Header() { 375e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 376e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 377e8696a40e09b24b634214684d18526187b316a2fJamie Gennis /** 378518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Return the currently set title. If {@link #titleRes} is set, 379518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * this resource is loaded from <var>res</var> and returned. Otherwise 380518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * {@link #title} is returned. 381518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 382518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public CharSequence getTitle(Resources res) { 383518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (titleRes != 0) { 384518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return res.getText(titleRes); 385518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 386518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return title; 387b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } 388b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall 389b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall /** 390518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Return the currently set summary. If {@link #summaryRes} is set, 391518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * this resource is loaded from <var>res</var> and returned. Otherwise 392518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * {@link #summary} is returned. 393518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 394518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public CharSequence getSummary(Resources res) { 3957773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian if (summaryRes != 0) { 396518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return res.getText(summaryRes); 397518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 398518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return summary; 399518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 400518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 401518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 402518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Return the currently set bread crumb title. If {@link #breadCrumbTitleRes} is set, 403518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * this resource is loaded from <var>res</var> and returned. Otherwise 404518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * {@link #breadCrumbTitle} is returned. 4057773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian */ 406518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public CharSequence getBreadCrumbTitle(Resources res) { 4077773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian if (breadCrumbTitleRes != 0) { 408518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return res.getText(breadCrumbTitleRes); 409518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 410518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return breadCrumbTitle; 411518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 412b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall 413b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall /** 4140469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * Return the currently set bread crumb short title. If 4150469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * {@link #breadCrumbShortTitleRes} is set, 4160469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * this resource is loaded from <var>res</var> and returned. Otherwise 4170469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * {@link #breadCrumbShortTitle} is returned. 418518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 419518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public CharSequence getBreadCrumbShortTitle(Resources res) { 420518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (breadCrumbShortTitleRes != 0) { 421518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return res.getText(breadCrumbShortTitleRes); 422518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 423518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return breadCrumbShortTitle; 424518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 425518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 426518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian @Override 427518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public int describeContents() { 428b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall return 0; 4295b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian } 4305b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian 431518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian @Override 432b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall public void writeToParcel(Parcel dest, int flags) { 4335b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian dest.writeLong(id); 4345b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian dest.writeInt(titleRes); 435518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian TextUtils.writeToParcel(title, dest, flags); 436518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian dest.writeInt(summaryRes); 437ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian TextUtils.writeToParcel(summary, dest, flags); 438518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian dest.writeInt(breadCrumbTitleRes); 439518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian TextUtils.writeToParcel(breadCrumbTitle, dest, flags); 440518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian dest.writeInt(breadCrumbShortTitleRes); 441518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian TextUtils.writeToParcel(breadCrumbShortTitle, dest, flags); 442518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian dest.writeInt(iconRes); 443518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian dest.writeString(fragment); 444518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian dest.writeBundle(fragmentArguments); 445518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (intent != null) { 446518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian dest.writeInt(1); 447518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian intent.writeToParcel(dest, flags); 448518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } else { 449b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall dest.writeInt(0); 450518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 451518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian dest.writeBundle(extras); 4525b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian } 4535b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian 4545b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian public void readFromParcel(Parcel in) { 455518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian id = in.readLong(); 456518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian titleRes = in.readInt(); 457518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian title = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); 458518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian summaryRes = in.readInt(); 459518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian summary = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); 460518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian breadCrumbTitleRes = in.readInt(); 461b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall breadCrumbTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); 462b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall breadCrumbShortTitleRes = in.readInt(); 463b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall breadCrumbShortTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); 464518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian iconRes = in.readInt(); 465518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian fragment = in.readString(); 4665b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian fragmentArguments = in.readBundle(); 467518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (in.readInt() != 0) { 468518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian intent = Intent.CREATOR.createFromParcel(in); 469518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 470518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian extras = in.readBundle(); 471518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 472518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 473518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Header(Parcel in) { 474518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian readFromParcel(in); 475518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 476518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 477518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public static final Creator<Header> CREATOR = new Creator<Header>() { 478518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public Header createFromParcel(Parcel source) { 479518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return new Header(source); 480518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 481518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public Header[] newArray(int size) { 482518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return new Header[size]; 483518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 484518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian }; 485518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 486518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 487518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian @Override 488518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian protected void onCreate(Bundle savedInstanceState) { 489518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian super.onCreate(savedInstanceState); 490518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 491518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian setContentView(com.android.internal.R.layout.preference_list_content); 492518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 493518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mListFooter = (FrameLayout)findViewById(com.android.internal.R.id.list_footer); 494518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mPrefsContainer = (ViewGroup) findViewById(com.android.internal.R.id.prefs_frame); 495518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian boolean hidingHeaders = onIsHidingHeaders(); 496518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mSinglePane = hidingHeaders || !onIsMultiPane(); 497518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian String initialFragment = getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT); 498518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Bundle initialArguments = getIntent().getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS); 499518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 500518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (savedInstanceState != null) { 501518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // We are restarting from a previous saved state; used that to 502518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // initialize, instead of starting fresh. 503518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ArrayList<Header> headers = savedInstanceState.getParcelableArrayList(HEADERS_TAG); 504518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (headers != null) { 505518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mHeaders.addAll(headers); 506518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian int curHeader = savedInstanceState.getInt(CUR_HEADER_TAG, 507518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian (int)HEADER_ID_UNDEFINED); 508518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (curHeader >= 0 && curHeader < mHeaders.size()) { 509518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian setSelectedHeader(mHeaders.get(curHeader)); 510518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 511518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 512518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 513b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } else { 514fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian if (initialFragment != null && mSinglePane) { 515fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian // If we are just showing a fragment, we want to run in 516518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // new fragment mode, but don't need to compute and show 517518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // the headers. 518fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian switchToHeader(initialFragment, initialArguments); 519518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 520518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } else { 5210469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy // We need to try to build the headers. 5220469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy onBuildHeaders(mHeaders); 52393a826f78f6313db791e6fc880439189897651b3Siva Velusamy 5240469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy // If there are headers, then at this point we need to show 525518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // them and, depending on the screen, we may also show in-line 526518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // the currently selected preference fragment. 527518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (mHeaders.size() > 0) { 528518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (!mSinglePane) { 529518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (initialFragment == null) { 530518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Header h = onGetInitialHeader(); 531518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian switchToHeader(h); 5325fecea776a5f093c21ac1a0ad3552b847d4be23eMathias Agopian } else { 533e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block switchToHeader(initialFragment, initialArguments); 5345fecea776a5f093c21ac1a0ad3552b847d4be23eMathias Agopian } 535518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 536518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 537518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 538518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 539518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 540518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // The default configuration is to only show the list view. Adjust 541518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // visibility for other configurations. 542518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (initialFragment != null && mSinglePane) { 543518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // Single pane, showing just a prefs fragment. 544518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian findViewById(com.android.internal.R.id.headers).setVisibility(View.GONE); 545b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall mPrefsContainer.setVisibility(View.VISIBLE); 546518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } else if (mHeaders.size() > 0) { 547518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mAdapter = new HeaderAdapter(this, mHeaders); 548b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall setListAdapter(mAdapter); 549518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (!mSinglePane) { 550518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // Multi-pane. 551518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian getListView().setChoiceMode(AbsListView.CHOICE_MODE_SINGLE); 5527773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian if (mCurHeader != null) { 5537773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian setSelectedHeader(mCurHeader); 554518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 555518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mPrefsContainer.setVisibility(View.VISIBLE); 556518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 557518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } else { 558518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // If there are no headers, we are in the old "just show a screen 559518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // of preferences" mode. 560518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian setContentView(com.android.internal.R.layout.preference_list_content_single); 561518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mListFooter = (FrameLayout) findViewById(com.android.internal.R.id.list_footer); 562518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mPrefsContainer = (ViewGroup) findViewById(com.android.internal.R.id.prefs); 563518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mPreferenceManager = new PreferenceManager(this, FIRST_REQUEST_CODE); 564518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mPreferenceManager.setOnPreferenceTreeClickListener(this); 565518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 566518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 567518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian getListView().setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); 568518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 569518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // see if we should show Back/Next buttons 570518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Intent intent = getIntent(); 571518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false)) { 572518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 573518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian findViewById(com.android.internal.R.id.button_bar).setVisibility(View.VISIBLE); 574518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 575518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Button backButton = (Button)findViewById(com.android.internal.R.id.back_button); 576518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian backButton.setOnClickListener(new OnClickListener() { 577518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public void onClick(View v) { 578518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian setResult(RESULT_CANCELED); 579518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian finish(); 580518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 581518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian }); 582518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Button skipButton = (Button)findViewById(com.android.internal.R.id.skip_button); 583518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian skipButton.setOnClickListener(new OnClickListener() { 584518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public void onClick(View v) { 585518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian setResult(RESULT_OK); 586518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian finish(); 587518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 588518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian }); 589518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mNextButton = (Button)findViewById(com.android.internal.R.id.next_button); 590518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mNextButton.setOnClickListener(new OnClickListener() { 591518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public void onClick(View v) { 592518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian setResult(RESULT_OK); 593518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian finish(); 594518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 595518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian }); 596518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 597518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // set our various button parameters 598518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (intent.hasExtra(EXTRA_PREFS_SET_NEXT_TEXT)) { 599518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_NEXT_TEXT); 600518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (TextUtils.isEmpty(buttonText)) { 601518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mNextButton.setVisibility(View.GONE); 602518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 603518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian else { 604518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mNextButton.setText(buttonText); 605518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 606518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 607518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (intent.hasExtra(EXTRA_PREFS_SET_BACK_TEXT)) { 608ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_BACK_TEXT); 609ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian if (TextUtils.isEmpty(buttonText)) { 610ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian backButton.setVisibility(View.GONE); 611ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian } 612ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian else { 613518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian backButton.setText(buttonText); 614518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 615518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 616518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_SKIP, false)) { 617518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian skipButton.setVisibility(View.VISIBLE); 618518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 619ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian } 620ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian } 621ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian 622ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian /** 623ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * Returns true if this activity is currently showing the header list. 624518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 625518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public boolean hasHeaders() { 626518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return getListView().getVisibility() == View.VISIBLE 627518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian && mPreferenceManager == null; 628ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian } 629ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian 630ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian /** 631ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * Returns true if this activity is showing multiple panes -- the headers 632518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * and a preference fragment. 633ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian */ 634ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian public boolean isMultiPane() { 635ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian return hasHeaders() && mPrefsContainer.getVisibility() == View.VISIBLE; 636ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian } 637518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 638518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 639518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Called to determine if the activity should run in multi-pane mode. 640518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * The default implementation returns true if the screen is large 641518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * enough. 642518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 643518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public boolean onIsMultiPane() { 644518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Configuration config = getResources().getConfiguration(); 645518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if ((config.screenLayout&Configuration.SCREENLAYOUT_SIZE_MASK) 646518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian == Configuration.SCREENLAYOUT_SIZE_XLARGE) { 647518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return true; 648518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 649518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if ((config.screenLayout&Configuration.SCREENLAYOUT_SIZE_MASK) 650518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian == Configuration.SCREENLAYOUT_SIZE_LARGE 651518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian && config.orientation == Configuration.ORIENTATION_LANDSCAPE) { 652aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis return true; 653aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis } 654c42fcf05ce253d5342993b28c412be16e61efffbJamie Gennis return false; 655aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis } 656aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis 657aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis /** 658518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Called to determine whether the header list should be hidden. 659518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * The default implementation returns the 660518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * value given in {@link #EXTRA_NO_HEADERS} or false if it is not supplied. 661518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * This is set to false, for example, when the activity is being re-launched 662aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis * to show a particular preference activity. 663518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 664518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public boolean onIsHidingHeaders() { 665518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return getIntent().getBooleanExtra(EXTRA_NO_HEADERS, false); 666518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 667518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 668518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 669518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Called to determine the initial header to be shown. The default 670518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * implementation simply returns the fragment of the first header. Note 671518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * that the returned Header object does not actually need to exist in 672518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * your header list -- whatever its fragment is will simply be used to 673518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * show for the initial UI. 674518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 675518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public Header onGetInitialHeader() { 676518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return mHeaders.get(0); 677518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 678518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 679518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 680518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Called after the header list has been updated ({@link #onBuildHeaders} 681518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * has been called and returned due to {@link #invalidateHeaders()}) to 682518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * specify the header that should now be selected. The default implementation 683518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * returns null to keep whatever header is currently selected. 684518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 685518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public Header onGetNewHeader() { 686518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return null; 687e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block } 688518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 689518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 690518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Called when the activity needs its list of headers build. By 6910469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * implementing this and adding at least one item to the list, you 6920469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * will cause the activity to run in its modern fragment mode. Note 6930469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * that this function may not always be called; for example, if the 6940469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * activity has been asked to display a particular fragment without 695518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * the header list, there is no need to build the headers. 696518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 697ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * <p>Typical implementations will use {@link #loadHeadersFromResource} 698ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * to fill in the list from a resource. 699ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * 700ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * @param target The list in which to place the headers. 701ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian */ 7027773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian public void onBuildHeaders(List<Header> target) { 7037773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian } 704518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 705ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian /** 706ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * Call when you need to change the headers being displayed. Will result 707518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * in onBuildHeaders() later being called to retrieve the new list. 708ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian */ 709518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public void invalidateHeaders() { 710ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian if (!mHandler.hasMessages(MSG_BUILD_HEADERS)) { 711518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mHandler.sendEmptyMessage(MSG_BUILD_HEADERS); 712518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 713518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 714518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 715518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 716518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Parse the given XML file as a header description, adding each 717518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * parsed Header into the target list. 718518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 719518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @param resid The XML resource to load and parse. 720518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @param target The list in which the parsed headers should be placed. 721518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 72228ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis public void loadHeadersFromResource(int resid, List<Header> target) { 72328ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis XmlResourceParser parser = null; 72428ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis try { 72528ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis parser = getResources().getXml(resid); 72628ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis AttributeSet attrs = Xml.asAttributeSet(parser); 72728ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis 72828ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis int type; 72928ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 73028ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis && type != XmlPullParser.START_TAG) { 73128ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis } 73228ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis 73328ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis String nodeName = parser.getName(); 73428ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis if (!"preference-headers".equals(nodeName)) { 73528ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis throw new RuntimeException( 73628ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis "XML document must start with <preference-headers> tag; found" 73728ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis + nodeName + " at " + parser.getPositionDescription()); 73828ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis } 73928ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis 74028ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis Bundle curBundle = null; 74128ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis 74228ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis final int outerDepth = parser.getDepth(); 74328ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 74428ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 74528ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 74628ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis continue; 74728ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis } 74828ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis 74928ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis nodeName = parser.getName(); 75028ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis if ("header".equals(nodeName)) { 75128ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis Header header = new Header(); 75228ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis 75328ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis TypedArray sa = getResources().obtainAttributes(attrs, 75428ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis com.android.internal.R.styleable.PreferenceHeader); 75528ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis header.id = sa.getResourceId( 75628ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis com.android.internal.R.styleable.PreferenceHeader_id, 75728ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis (int)HEADER_ID_UNDEFINED); 75828ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis TypedValue tv = sa.peekValue( 75928ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis com.android.internal.R.styleable.PreferenceHeader_title); 76028ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis if (tv != null && tv.type == TypedValue.TYPE_STRING) { 76128ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis if (tv.resourceId != 0) { 76228ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis header.titleRes = tv.resourceId; 76328ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis } else { 76428ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis header.title = tv.string; 76528ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis } 76628ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis } 76728ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis tv = sa.peekValue( 76828ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis com.android.internal.R.styleable.PreferenceHeader_summary); 76928ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis if (tv != null && tv.type == TypedValue.TYPE_STRING) { 77028ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis if (tv.resourceId != 0) { 77128ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis header.summaryRes = tv.resourceId; 77228ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis } else { 77328ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis header.summary = tv.string; 77428ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis } 77528ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis } 77628ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis tv = sa.peekValue( 77728ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis com.android.internal.R.styleable.PreferenceHeader_breadCrumbTitle); 77828ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis if (tv != null && tv.type == TypedValue.TYPE_STRING) { 77928ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis if (tv.resourceId != 0) { 78028ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis header.breadCrumbTitleRes = tv.resourceId; 78128ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis } else { 78228ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis header.breadCrumbTitle = tv.string; 78328ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis } 78428ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis } 785518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian tv = sa.peekValue( 786518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian com.android.internal.R.styleable.PreferenceHeader_breadCrumbShortTitle); 7871c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis if (tv != null && tv.type == TypedValue.TYPE_STRING) { 788518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (tv.resourceId != 0) { 789518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian header.breadCrumbShortTitleRes = tv.resourceId; 790b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } else { 791518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian header.breadCrumbShortTitle = tv.string; 792518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 793b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } 7945b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian header.iconRes = sa.getResourceId( 7955b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian com.android.internal.R.styleable.PreferenceHeader_icon, 0); 796518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian header.fragment = sa.getString( 7970469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy com.android.internal.R.styleable.PreferenceHeader_fragment); 7980469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy sa.recycle(); 7990469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 8000469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy if (curBundle == null) { 8010469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy curBundle = new Bundle(); 802518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 8037db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian 8047db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian final int innerDepth = parser.getDepth(); 8057db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 8067db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) { 8077db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 8087db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian continue; 8097db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian } 8107db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian 8117db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian String innerNodeName = parser.getName(); 8127db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian if (innerNodeName.equals("extra")) { 8137db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian getResources().parseBundleExtra("extra", attrs, curBundle); 81428ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis XmlUtils.skipCurrentTag(parser); 81528ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis 81628ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis } else if (innerNodeName.equals("intent")) { 81728ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis header.intent = Intent.parseIntent(getResources(), parser, attrs); 81828ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis 81928ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis } else { 82028ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis XmlUtils.skipCurrentTag(parser); 82128ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis } 82228ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis } 82328ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis 82428ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis if (curBundle.size() > 0) { 82528ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis header.fragmentArguments = curBundle; 82628ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis curBundle = null; 827518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 828518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 829518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian target.add(header); 830518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } else { 831518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian XmlUtils.skipCurrentTag(parser); 832518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 833518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 834b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall 835518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } catch (XmlPullParserException e) { 836518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian throw new RuntimeException("Error parsing headers", e); 837b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } catch (IOException e) { 8385b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian throw new RuntimeException("Error parsing headers", e); 8395b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian } finally { 840518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (parser != null) parser.close(); 841518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 842ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian 843518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 844518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 845518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 846518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Set a footer that should be shown at the bottom of the header list. 847518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 848518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public void setListFooter(View view) { 849b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall mListFooter.removeAllViews(); 850518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mListFooter.addView(view, new FrameLayout.LayoutParams( 851518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian FrameLayout.LayoutParams.MATCH_PARENT, 852518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian FrameLayout.LayoutParams.WRAP_CONTENT)); 853518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 8544b9511c16195a646242eff833b0af212933b6ecaMathias Agopian 855518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian @Override 8564b9511c16195a646242eff833b0af212933b6ecaMathias Agopian protected void onStop() { 857518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian super.onStop(); 8584b9511c16195a646242eff833b0af212933b6ecaMathias Agopian 859518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (mPreferenceManager != null) { 8604b9511c16195a646242eff833b0af212933b6ecaMathias Agopian mPreferenceManager.dispatchActivityStop(); 861ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian } 862ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian } 863518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 864518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian @Override 865518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian protected void onDestroy() { 866518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian super.onDestroy(); 867518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 868518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (mPreferenceManager != null) { 869518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mPreferenceManager.dispatchActivityDestroy(); 870518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 871518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 872518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 873518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian @Override 874518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian protected void onSaveInstanceState(Bundle outState) { 875518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian super.onSaveInstanceState(outState); 876518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 877b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall if (mHeaders.size() > 0) { 878518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian outState.putParcelableArrayList(HEADERS_TAG, mHeaders); 879518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (mCurHeader != null) { 880b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall int index = mHeaders.indexOf(mCurHeader); 8815b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian if (index >= 0) { 8825b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian outState.putInt(CUR_HEADER_TAG, index); 883518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 884518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 885518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 886518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 887ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian if (mPreferenceManager != null) { 888518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian final PreferenceScreen preferenceScreen = getPreferenceScreen(); 889518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (preferenceScreen != null) { 890518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Bundle container = new Bundle(); 891518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian preferenceScreen.saveHierarchyState(container); 892518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian outState.putBundle(PREFERENCES_TAG, container); 893518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 894518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 895518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 896518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 897b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall @Override 898518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian protected void onRestoreInstanceState(Bundle state) { 899518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (mPreferenceManager != null) { 900b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall Bundle container = state.getBundle(PREFERENCES_TAG); 9015b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian if (container != null) { 9025b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian final PreferenceScreen preferenceScreen = getPreferenceScreen(); 903518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (preferenceScreen != null) { 904518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian preferenceScreen.restoreHierarchyState(container); 905518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mSavedInstanceState = state; 906518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return; 907ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian } 908518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 909518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 910518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 911518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // Only call this if we didn't save the instance state for later. 912518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // If we did save it, it will be restored when we bind the adapter. 913518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian super.onRestoreInstanceState(state); 914518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 915518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 916518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian @Override 917b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall protected void onActivityResult(int requestCode, int resultCode, Intent data) { 918518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian super.onActivityResult(requestCode, resultCode, data); 919518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 920b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall if (mPreferenceManager != null) { 9215b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian mPreferenceManager.dispatchActivityResult(requestCode, resultCode, data); 9225b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian } 923518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 924518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 925518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian @Override 926518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public void onContentChanged() { 927ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian super.onContentChanged(); 928518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 929518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (mPreferenceManager != null) { 930518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian postBindPreferences(); 931518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 932518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 933518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 934518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian @Override 935518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian protected void onListItemClick(ListView l, View v, int position, long id) { 936b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall super.onListItemClick(l, v, position, id); 937518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 938518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (mAdapter != null) { 939518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian onHeaderClick(mHeaders.get(position), position); 940ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian } 941ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian } 942ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian 943518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 944ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * Called when the user selects an item in the header list. The default 945518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * implementation will call either {@link #startWithFragment(String, Bundle, Fragment, int)} 946518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * or {@link #switchToHeader(Header)} as appropriate. 947518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 948518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @param header The header that was selected. 949518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @param position The header's position in the list. 950518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 951518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public void onHeaderClick(Header header, int position) { 952518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (header.fragment != null) { 953518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (mSinglePane) { 954518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian startWithFragment(header.fragment, header.fragmentArguments, null, 0); 955518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } else { 956518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian switchToHeader(header); 957ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian } 958ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian } else if (header.intent != null) { 959ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian startActivity(header.intent); 960ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian } 961ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian } 962ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian 963ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian /** 964ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * Start a new instance of this activity, showing only the given 965ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * preference fragment. When launched in this mode, the header list 966518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * will be hidden and the given preference fragment will be instantiated 967518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * and fill the entire activity. 968518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 969518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @param fragmentName The name of the fragment to display. 970518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @param args Optional arguments to supply to the fragment. 971518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 972518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public void startWithFragment(String fragmentName, Bundle args, 973518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Fragment resultTo, int resultRequestCode) { 974518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Intent intent = new Intent(Intent.ACTION_MAIN); 975518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian intent.setClass(this, getClass()); 976518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian intent.putExtra(EXTRA_SHOW_FRAGMENT, fragmentName); 977518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian intent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args); 978518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian intent.putExtra(EXTRA_NO_HEADERS, true); 979518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (resultTo == null) { 980ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian startActivity(intent); 981ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian } else { 982ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian resultTo.startActivityForResult(intent, resultRequestCode); 983518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 984518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 985518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 986518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 987518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Change the base title of the bread crumbs for the current preferences. 988518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * This will normally be called for you. See 989518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * {@link android.app.FragmentBreadCrumbs} for more information. 990518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 991518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public void showBreadCrumbs(CharSequence title, CharSequence shortTitle) { 992518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (mFragmentBreadCrumbs == null) { 993518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian View crumbs = findViewById(android.R.id.title); 994518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // For screens with a different kind of title, don't create breadcrumbs. 995ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian if (!(crumbs instanceof FragmentBreadCrumbs)) return; 996ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian mFragmentBreadCrumbs = (FragmentBreadCrumbs) findViewById(android.R.id.title); 997ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian if (mFragmentBreadCrumbs == null) { 998518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mFragmentBreadCrumbs = new FragmentBreadCrumbs(this); 999ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian ActionBar actionBar = getActionBar(); 1000518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (actionBar != null) { 1001518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian actionBar.setCustomNavigationMode(mFragmentBreadCrumbs); 1002518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1003518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1004518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mFragmentBreadCrumbs.setMaxVisible(2); 1005518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mFragmentBreadCrumbs.setActivity(this); 1006518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1007518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mFragmentBreadCrumbs.setTitle(title, shortTitle); 1008518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mFragmentBreadCrumbs.setParentTitle(null, null, null); 1009fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian } 1010518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 1011ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian /** 1012ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * Should be called after onCreate to ensure that the breadcrumbs, if any, were created. 1013ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * This prepends a title to the fragment breadcrumbs and attaches a listener to any clicks 1014518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * on the parent entry. 1015ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * @param title the title for the breadcrumb 1016518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @param shortTitle the short title for the breadcrumb 10170469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy */ 10180469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy public void setParentTitle(CharSequence title, CharSequence shortTitle, 10190469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy OnClickListener listener) { 10200469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy if (mFragmentBreadCrumbs != null) { 1021518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mFragmentBreadCrumbs.setParentTitle(title, shortTitle, listener); 1022518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1023518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1024518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 1025518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian void setSelectedHeader(Header header) { 1026518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian mCurHeader = header; 1027518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian int index = mHeaders.indexOf(header); 1028518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (index >= 0) { 1029518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian getListView().setItemChecked(index, true); 1030b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } else { 1031b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall getListView().clearChoices(); 1032b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } 1033518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (header != null) { 1034518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian CharSequence title = header.getBreadCrumbTitle(getResources()); 10357773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian if (title == null) title = header.getTitle(getResources()); 1036518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (title == null) title = getTitle(); 1037518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian showBreadCrumbs(title, header.getBreadCrumbShortTitle(getResources())); 1038518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } else { 1039518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian showBreadCrumbs(getTitle(), null); 1040518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1041518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1042518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 1043518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian private void switchToHeaderInner(String fragmentName, Bundle args, int direction) { 1044518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian getFragmentManager().popBackStack(BACK_STACK_PREFS, 1045518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian FragmentManager.POP_BACK_STACK_INCLUSIVE); 1046518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Fragment f = Fragment.instantiate(this, fragmentName, args); 1047518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian FragmentTransaction transaction = getFragmentManager().beginTransaction(); 1048518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); 1049b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall transaction.replace(com.android.internal.R.id.prefs, f); 1050518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian transaction.commit(); 1051518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1052b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall 10535b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian /** 10545b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian * When in two-pane mode, switch the fragment pane to show the given 1055518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * preference fragment. 1056518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * 1057518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @param fragmentName The name of the fragment to display. 1058518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @param args Optional arguments to supply to the fragment. 1059ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian */ 1060518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public void switchToHeader(String fragmentName, Bundle args) { 1061518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian setSelectedHeader(null); 1062518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian switchToHeaderInner(fragmentName, args, 0); 1063518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1064518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 1065518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 1066518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * When in two-pane mode, switch to the fragment pane to show the given 1067518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * preference fragment. 1068b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall * 1069518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @param header The new header to display. 1070518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 1071b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall public void switchToHeader(Header header) { 10725b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian if (mCurHeader == header) { 10735b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian // This is the header we are currently displaying. Just make sure 1074518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // to pop the stack up to its root state. 1075518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian getFragmentManager().popBackStack(BACK_STACK_PREFS, 1076518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian FragmentManager.POP_BACK_STACK_INCLUSIVE); 1077ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian } else { 1078518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian int direction = mHeaders.indexOf(header) - mHeaders.indexOf(mCurHeader); 1079518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian switchToHeaderInner(header.fragment, header.fragmentArguments, direction); 1080518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian setSelectedHeader(header); 1081518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1082518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1083518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 1084518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Header findBestMatchingHeader(Header cur, ArrayList<Header> from) { 1085518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ArrayList<Header> matches = new ArrayList<Header>(); 1086518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian for (int j=0; j<from.size(); j++) { 1087b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall Header oh = from.get(j); 1088518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (cur == oh || (cur.id != HEADER_ID_UNDEFINED && cur.id == oh.id)) { 1089518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // Must be this one. 1090b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall matches.clear(); 10917c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian matches.add(oh); 1092518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian break; 10937c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian } 10947c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian if (cur.fragment != null) { 10957c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian if (cur.fragment.equals(oh.fragment)) { 10967c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian matches.add(oh); 10977c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian } 10987c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian } else if (cur.intent != null) { 10997c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian if (cur.intent.equals(oh.intent)) { 1100518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian matches.add(oh); 11017c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian } 1102518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } else if (cur.title != null) { 1103518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (cur.title.equals(oh.title)) { 1104518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian matches.add(oh); 1105518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1106518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1107518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1108b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall final int NM = matches.size(); 1109518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (NM == 1) { 1110518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return matches.get(0); 1111ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian } else if (NM > 1) { 11127c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian for (int j=0; j<NM; j++) { 11137c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian Header oh = matches.get(j); 1114518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (cur.fragmentArguments != null && 1115518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian cur.fragmentArguments.equals(oh.fragmentArguments)) { 1116518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return oh; 1117518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1118518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (cur.extras != null && cur.extras.equals(oh.extras)) { 1119518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return oh; 1120518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1121518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (cur.title != null && cur.title.equals(oh.title)) { 1122518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return oh; 1123518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1124518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1125518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1126518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return null; 1127b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } 1128518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 1129518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 1130518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Start a new fragment. 11317c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian * 11327c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian * @param fragment The fragment to start 11337c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian * @param push If true, the current fragment will be pushed onto the back stack. If false, 1134518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * the current fragment will be replaced. 11357c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian */ 1136518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian public void startPreferenceFragment(Fragment fragment, boolean push) { 1137518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian FragmentTransaction transaction = getFragmentManager().beginTransaction(); 1138518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian transaction.replace(com.android.internal.R.id.prefs, fragment); 1139518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (push) { 1140518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 1141518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian transaction.addToBackStack(BACK_STACK_PREFS); 1142b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } else { 1143518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); 1144518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1145518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian transaction.commit(); 11467c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian } 11477c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian 11487c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian /** 1149518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Start a new fragment containing a preference panel. If the prefences 1150518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * are being displayed in multi-pane mode, the given fragment class will 1151518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * be instantiated and placed in the appropriate pane. If running in 1152518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * single-pane mode, a new activity will be launched in which to show the 11537c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian * fragment. 11547c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian * 1155518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @param fragmentClass Full name of the class implementing the fragment. 1156518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @param args Any desired arguments to supply to the fragment. 1157518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @param titleRes Optional resource identifier of the title of this 1158b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall * fragment. 1159518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @param titleText Optional text of the title of this fragment. 1160518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * @param resultTo Optional fragment that result data should be sent to. 11617c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian * If non-null, resultTo.onActivityResult() will be called when this 11627c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian * preference panel is done. The launched panel must use 11637c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian * {@link #finishPreferencePanel(Fragment, int, Intent)} when done. 11647c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian * @param resultRequestCode If resultTo is non-null, this is the caller's 11657c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian * request code to be received with the resut. 1166518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 11677c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian public void startPreferencePanel(String fragmentClass, Bundle args, int titleRes, 1168518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian CharSequence titleText, Fragment resultTo, int resultRequestCode) { 1169518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (mSinglePane) { 11707c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian startWithFragment(fragmentClass, args, resultTo, resultRequestCode); 11717c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian } else { 1172518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian Fragment f = Fragment.instantiate(this, fragmentClass, args); 1173518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (resultTo != null) { 1174518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian f.setTargetFragment(resultTo, resultRequestCode); 1175b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall } 1176518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian FragmentTransaction transaction = getFragmentManager().beginTransaction(); 1177518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian transaction.replace(com.android.internal.R.id.prefs, f); 11787c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian if (titleRes != 0) { 11797c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian transaction.setBreadCrumbTitle(titleRes); 11807c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian } else if (titleText != null) { 11817c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian transaction.setBreadCrumbTitle(titleText); 11827c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian } 1183518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 11847c0441ac271f4e00a2d63eb3048c037ebffa90b9Mathias Agopian transaction.addToBackStack(BACK_STACK_PREFS); 1185518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian transaction.commit(); 1186518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1187518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 1188518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 1189518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian /** 1190518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian * Called by a preference panel fragment to finish itself. 11914b9511c16195a646242eff833b0af212933b6ecaMathias Agopian * 11921c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang * @param caller The fragment that is asking to be finished. 11931c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang * @param resultCode Optional result code to send back to the original 11941c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang * launching fragment. 11951c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang * @param resultData Optional result data to send back to the original 11961c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang * launching fragment. 11971c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang */ 11981c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang public void finishPreferencePanel(Fragment caller, int resultCode, Intent resultData) { 11991c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang if (mSinglePane) { 12001c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang setResult(resultCode, resultData); 12011c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang finish(); 12021c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang } else { 12031c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang // XXX be smarter about popping the stack. 12041c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang onBackPressed(); 1205ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian if (caller != null) { 12061c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang if (caller.getTargetFragment() != null) { 1207ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian caller.getTargetFragment().onActivityResult(caller.getTargetRequestCode(), 1208ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian resultCode, resultData); 12091c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang } 12101c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang } 12110e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian } 12121c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang } 12131c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang 12141c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang @Override 12151c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) { 12161c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang startPreferencePanel(pref.getFragment(), pref.getExtras(), 0, pref.getTitle(), null, 0); 12171c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang return true; 12181c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang } 12191c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang 12201c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang /** 12211c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang * Posts a message to bind the preferences to the list view. 12221c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang * <p> 1223ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian * Binding late is preferred as any custom preference types created in 12241c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang * {@link #onCreate(Bundle)} are able to have their views recycled. 1225ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian */ 1226ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian private void postBindPreferences() { 12271c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) return; 12281c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget(); 12290e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian } 12301c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang 1231 private void bindPreferences() { 1232 final PreferenceScreen preferenceScreen = getPreferenceScreen(); 1233 if (preferenceScreen != null) { 1234 preferenceScreen.bind(getListView()); 1235 if (mSavedInstanceState != null) { 1236 super.onRestoreInstanceState(mSavedInstanceState); 1237 mSavedInstanceState = null; 1238 } 1239 } 1240 } 1241 1242 /** 1243 * Returns the {@link PreferenceManager} used by this activity. 1244 * @return The {@link PreferenceManager}. 1245 * 1246 * @deprecated This function is not relevant for a modern fragment-based 1247 * PreferenceActivity. 1248 */ 1249 @Deprecated 1250 public PreferenceManager getPreferenceManager() { 1251 return mPreferenceManager; 1252 } 1253 1254 private void requirePreferenceManager() { 1255 if (mPreferenceManager == null) { 1256 if (mAdapter == null) { 1257 throw new RuntimeException("This should be called after super.onCreate."); 1258 } 1259 throw new RuntimeException( 1260 "Modern two-pane PreferenceActivity requires use of a PreferenceFragment"); 1261 } 1262 } 1263 1264 /** 1265 * Sets the root of the preference hierarchy that this activity is showing. 1266 * 1267 * @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy. 1268 * 1269 * @deprecated This function is not relevant for a modern fragment-based 1270 * PreferenceActivity. 1271 */ 1272 @Deprecated 1273 public void setPreferenceScreen(PreferenceScreen preferenceScreen) { 1274 requirePreferenceManager(); 1275 1276 if (mPreferenceManager.setPreferences(preferenceScreen) && preferenceScreen != null) { 1277 postBindPreferences(); 1278 CharSequence title = getPreferenceScreen().getTitle(); 1279 // Set the title of the activity 1280 if (title != null) { 1281 setTitle(title); 1282 } 1283 } 1284 } 1285 1286 /** 1287 * Gets the root of the preference hierarchy that this activity is showing. 1288 * 1289 * @return The {@link PreferenceScreen} that is the root of the preference 1290 * hierarchy. 1291 * 1292 * @deprecated This function is not relevant for a modern fragment-based 1293 * PreferenceActivity. 1294 */ 1295 @Deprecated 1296 public PreferenceScreen getPreferenceScreen() { 1297 if (mPreferenceManager != null) { 1298 return mPreferenceManager.getPreferenceScreen(); 1299 } 1300 return null; 1301 } 1302 1303 /** 1304 * Adds preferences from activities that match the given {@link Intent}. 1305 * 1306 * @param intent The {@link Intent} to query activities. 1307 * 1308 * @deprecated This function is not relevant for a modern fragment-based 1309 * PreferenceActivity. 1310 */ 1311 @Deprecated 1312 public void addPreferencesFromIntent(Intent intent) { 1313 requirePreferenceManager(); 1314 1315 setPreferenceScreen(mPreferenceManager.inflateFromIntent(intent, getPreferenceScreen())); 1316 } 1317 1318 /** 1319 * Inflates the given XML resource and adds the preference hierarchy to the current 1320 * preference hierarchy. 1321 * 1322 * @param preferencesResId The XML resource ID to inflate. 1323 * 1324 * @deprecated This function is not relevant for a modern fragment-based 1325 * PreferenceActivity. 1326 */ 1327 @Deprecated 1328 public void addPreferencesFromResource(int preferencesResId) { 1329 requirePreferenceManager(); 1330 1331 setPreferenceScreen(mPreferenceManager.inflateFromResource(this, preferencesResId, 1332 getPreferenceScreen())); 1333 } 1334 1335 /** 1336 * {@inheritDoc} 1337 * 1338 * @deprecated This function is not relevant for a modern fragment-based 1339 * PreferenceActivity. 1340 */ 1341 @Deprecated 1342 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { 1343 return false; 1344 } 1345 1346 /** 1347 * Finds a {@link Preference} based on its key. 1348 * 1349 * @param key The key of the preference to retrieve. 1350 * @return The {@link Preference} with the key, or null. 1351 * @see PreferenceGroup#findPreference(CharSequence) 1352 * 1353 * @deprecated This function is not relevant for a modern fragment-based 1354 * PreferenceActivity. 1355 */ 1356 @Deprecated 1357 public Preference findPreference(CharSequence key) { 1358 1359 if (mPreferenceManager == null) { 1360 return null; 1361 } 1362 1363 return mPreferenceManager.findPreference(key); 1364 } 1365 1366 @Override 1367 protected void onNewIntent(Intent intent) { 1368 if (mPreferenceManager != null) { 1369 mPreferenceManager.dispatchNewIntent(intent); 1370 } 1371 } 1372 1373 // give subclasses access to the Next button 1374 /** @hide */ 1375 protected boolean hasNextButton() { 1376 return mNextButton != null; 1377 } 1378 /** @hide */ 1379 protected Button getNextButton() { 1380 return mNextButton; 1381 } 1382} 1383