16904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler/* 26904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Copyright (C) 2015 The Android Open Source Project 36904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 46904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Licensed under the Apache License, Version 2.0 (the "License"); 56904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * you may not use this file except in compliance with the License. 66904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * You may obtain a copy of the License at 76904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 86904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * http://www.apache.org/licenses/LICENSE-2.0 96904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 106904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Unless required by applicable law or agreed to in writing, software 116904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * distributed under the License is distributed on an "AS IS" BASIS, 126904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * See the License for the specific language governing permissions and 146904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * limitations under the License 156904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 166904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 176904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerpackage android.support.v14.preference; 186904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 196904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.app.DialogFragment; 206904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.app.Fragment; 216904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.content.Context; 226904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.content.res.TypedArray; 231fcd004668b5a9038c312e4426031027d8641353Tony Mantlerimport android.graphics.Canvas; 241fcd004668b5a9038c312e4426031027d8641353Tony Mantlerimport android.graphics.Rect; 251fcd004668b5a9038c312e4426031027d8641353Tony Mantlerimport android.graphics.drawable.Drawable; 266904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.os.Bundle; 276904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.os.Handler; 286904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.os.Message; 296904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.annotation.Nullable; 306904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.annotation.XmlRes; 313fadd62b614e4a69aefe920aac640bdb629e502eJason Monkimport android.support.v4.content.res.TypedArrayUtils; 321fcd004668b5a9038c312e4426031027d8641353Tony Mantlerimport android.support.v4.view.ViewCompat; 333fadd62b614e4a69aefe920aac640bdb629e502eJason Monkimport android.support.v7.preference.AndroidResources; 346904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.v7.preference.DialogPreference; 356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.v7.preference.EditTextPreference; 366904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.v7.preference.ListPreference; 376904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.v7.preference.Preference; 3866222008cbda61251014caf1442930a48561d25cTony Mantlerimport android.support.v7.preference.PreferenceGroup; 3953b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantlerimport android.support.v7.preference.PreferenceGroupAdapter; 406904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.v7.preference.PreferenceManager; 411553af7799b550e0821a5e579db0bccf1f0835b8Steven Daoimport android.support.v7.preference.PreferenceRecyclerViewAccessibilityDelegate; 426904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.v7.preference.PreferenceScreen; 431fcd004668b5a9038c312e4426031027d8641353Tony Mantlerimport android.support.v7.preference.PreferenceViewHolder; 446904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.v7.widget.LinearLayoutManager; 456904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.v7.widget.RecyclerView; 466904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.util.TypedValue; 476904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.view.ContextThemeWrapper; 486904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.view.LayoutInflater; 496904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.view.View; 506904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.view.ViewGroup; 516904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 526904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler/** 536904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Shows a hierarchy of {@link Preference} objects as 546904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * lists. These preferences will 556904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * automatically save to {@link android.content.SharedPreferences} as the user interacts with 566904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * them. To retrieve an instance of {@link android.content.SharedPreferences} that the 576904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * preference hierarchy in this fragment will use, call 586904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link PreferenceManager#getDefaultSharedPreferences(android.content.Context)} 596904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * with a context in the same package as this fragment. 606904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <p> 616904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Furthermore, the preferences shown will follow the visual style of system 626904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * preferences. It is easy to create a hierarchy of preferences (that can be 636904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * shown on multiple screens) via XML. For these reasons, it is recommended to 646904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * use this fragment (as a superclass) to deal with preferences in applications. 656904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <p> 666904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * A {@link PreferenceScreen} object should be at the top of the preference 676904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * hierarchy. Furthermore, subsequent {@link PreferenceScreen} in the hierarchy 686904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * denote a screen break--that is the preferences contained within subsequent 696904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link PreferenceScreen} should be shown on another screen. The preference 70ee1e0dfa158dab873977c50c746749f55a4c1251Tony Mantler * framework handles this by calling {@link #onNavigateToScreen(PreferenceScreen)}. 716904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <p> 726904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * The preference hierarchy can be formed in multiple ways: 736904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <li> From an XML file specifying the hierarchy 746904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <li> From different {@link android.app.Activity Activities} that each specify its own 756904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * preferences in an XML file via {@link android.app.Activity} meta-data 766904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <li> From an object hierarchy rooted with {@link PreferenceScreen} 776904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <p> 786904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * To inflate from XML, use the {@link #addPreferencesFromResource(int)}. The 796904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * root element should be a {@link PreferenceScreen}. Subsequent elements can point 806904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * to actual {@link Preference} subclasses. As mentioned above, subsequent 816904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link PreferenceScreen} in the hierarchy will result in the screen break. 826904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <p> 836904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * To specify an object hierarchy rooted with {@link PreferenceScreen}, use 846904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link #setPreferenceScreen(PreferenceScreen)}. 856904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <p> 866904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * As a convenience, this fragment implements a click listener for any 876904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * preference in the current hierarchy, see 886904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link #onPreferenceTreeClick(Preference)}. 896904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 906904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <div class="special reference"> 916904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <h3>Developer Guides</h3> 926904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <p>For information about using {@code PreferenceFragment}, 936904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * read the <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a> 946904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * guide.</p> 956904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * </div> 966904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 976904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <a name="SampleCode"></a> 986904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <h3>Sample Code</h3> 996904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 1006904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <p>The following sample code shows a simple preference fragment that is 1016904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * populated from a resource. The resource it loads is:</p> 1026904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 1036904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@sample development/samples/ApiDemos/res/xml/preferences.xml preferences} 1046904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 1056904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <p>The fragment implementation itself simply populates the preferences 1066904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * when created. Note that the preferences framework takes care of loading 1076904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * the current values out of the app preferences and writing them when changed:</p> 1086904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 1096904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@sample development/samples/ApiDemos/src/com/example/android/apis/preference/FragmentPreferences.java 1106904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * fragment} 1116904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 1126904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @see Preference 1136904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @see PreferenceScreen 1146904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 1156904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerpublic abstract class PreferenceFragment extends Fragment implements 1166904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler PreferenceManager.OnPreferenceTreeClickListener, 1176904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler PreferenceManager.OnDisplayPreferenceDialogListener, 1186904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler PreferenceManager.OnNavigateToScreenListener, 1196904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler DialogPreference.TargetFragment { 1206904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1216904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 1226904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Fragment argument used to specify the tag of the desired root 1236904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link android.support.v7.preference.PreferenceScreen} object. 1246904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 1256904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public static final String ARG_PREFERENCE_ROOT = 1266904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler "android.support.v7.preference.PreferenceFragmentCompat.PREFERENCE_ROOT"; 1276904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1286904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private static final String PREFERENCES_TAG = "android:preferences"; 1296904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1306904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private static final String DIALOG_FRAGMENT_TAG = 1316904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler "android.support.v14.preference.PreferenceFragment.DIALOG"; 1326904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1336904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private PreferenceManager mPreferenceManager; 1346904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private RecyclerView mList; 1356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private boolean mHavePrefs; 1366904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private boolean mInitDone; 1376904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1386904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private Context mStyledContext; 1396904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1406759b1021d8198ad1d239bb30e5a102b99624bceAdam Lesinski private int mLayoutResId = android.support.v7.preference.R.layout.preference_list_fragment; 1416904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1421fcd004668b5a9038c312e4426031027d8641353Tony Mantler private final DividerDecoration mDividerDecoration = new DividerDecoration(); 1431fcd004668b5a9038c312e4426031027d8641353Tony Mantler 1446904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private static final int MSG_BIND_PREFERENCES = 1; 1456904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private Handler mHandler = new Handler() { 1466904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler @Override 1476904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void handleMessage(Message msg) { 1486904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler switch (msg.what) { 1496904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1506904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler case MSG_BIND_PREFERENCES: 1516904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler bindPreferences(); 1526904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler break; 1536904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 1546904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 1556904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler }; 1566904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1576904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final private Runnable mRequestFocus = new Runnable() { 1586904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void run() { 1596904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mList.focusableViewAvailable(mList); 1606904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 1616904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler }; 1626904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 16366222008cbda61251014caf1442930a48561d25cTony Mantler private Runnable mSelectPreferenceRunnable; 16466222008cbda61251014caf1442930a48561d25cTony Mantler 1656904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 1666904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Interface that PreferenceFragment's containing activity should 1676904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * implement to be able to process preference items that wish to 1686904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * switch to a specified fragment. 1696904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 1706904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public interface OnPreferenceStartFragmentCallback { 1716904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 1726904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Called when the user has clicked on a Preference that has 1736904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * a fragment class name associated with it. The implementation 17453b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler * should instantiate and switch to an instance of the given 1756904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * fragment. 176bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler * @param caller The fragment requesting navigation. 177bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler * @param pref The preference requesting the fragment. 178bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler * @return true if the fragment creation has been handled 1796904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 1806904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref); 1816904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 1826904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1836904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 1846904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Interface that PreferenceFragment's containing activity should 1856904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * implement to be able to process preference items that wish to 1866904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * switch to a new screen of preferences. 1876904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 1886904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public interface OnPreferenceStartScreenCallback { 1896904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 1906904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Called when the user has clicked on a PreferenceScreen item in order to navigate to a new 1916904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * screen of preferences. 1926904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param caller The fragment requesting navigation. 1936904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param pref The preference screen to navigate to. 194bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler * @return true if the screen navigation has been handled 1956904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 1966904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler boolean onPreferenceStartScreen(PreferenceFragment caller, PreferenceScreen pref); 1976904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 1986904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 199bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler public interface OnPreferenceDisplayDialogCallback { 200bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler 201bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler /** 202bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler * 203bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler * @param caller The fragment containing the preference requesting the dialog. 204bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler * @param pref The preference requesting the dialog. 205bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler * @return true if the dialog creation has been handled. 206bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler */ 207bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler boolean onPreferenceDisplayDialog(PreferenceFragment caller, Preference pref); 208bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler } 209bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler 2106904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler @Override 2116904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void onCreate(Bundle savedInstanceState) { 2126904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler super.onCreate(savedInstanceState); 2136904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final TypedValue tv = new TypedValue(); 2146759b1021d8198ad1d239bb30e5a102b99624bceAdam Lesinski getActivity().getTheme().resolveAttribute( 2156759b1021d8198ad1d239bb30e5a102b99624bceAdam Lesinski android.support.v7.preference.R.attr.preferenceTheme, tv, true); 2166904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final int theme = tv.resourceId; 2176904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (theme <= 0) { 2186904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler throw new IllegalStateException("Must specify preferenceTheme in theme"); 2196904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 2206904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mStyledContext = new ContextThemeWrapper(getActivity(), theme); 2216904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2226904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mPreferenceManager = new PreferenceManager(mStyledContext); 2236904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mPreferenceManager.setOnNavigateToScreenListener(this); 2246904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final Bundle args = getArguments(); 2256904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final String rootKey; 2266904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (args != null) { 2276904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler rootKey = getArguments().getString(ARG_PREFERENCE_ROOT); 2286904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } else { 2296904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler rootKey = null; 2306904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 2316904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler onCreatePreferences(savedInstanceState, rootKey); 2326904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 2336904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2346904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 2356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Called during {@link #onCreate(Bundle)} to supply the preferences for this fragment. 2366904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Subclasses are expected to call {@link #setPreferenceScreen(PreferenceScreen)} either 2376904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * directly or via helper methods such as {@link #addPreferencesFromResource(int)}. 2386904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 2396904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param savedInstanceState If the fragment is being re-created from 2406904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * a previous saved state, this is the state. 2416904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param rootKey If non-null, this preference fragment should be rooted at the 2426904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link android.support.v7.preference.PreferenceScreen} with this key. 2436904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 2446904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public abstract void onCreatePreferences(Bundle savedInstanceState, String rootKey); 2456904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2466904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler @Override 2476904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public View onCreateView(LayoutInflater inflater, ViewGroup container, 2486904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler Bundle savedInstanceState) { 2496904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2506904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler TypedArray a = mStyledContext.obtainStyledAttributes(null, 2511fcd004668b5a9038c312e4426031027d8641353Tony Mantler R.styleable.PreferenceFragment, 2526759b1021d8198ad1d239bb30e5a102b99624bceAdam Lesinski TypedArrayUtils.getAttr(mStyledContext, 2536759b1021d8198ad1d239bb30e5a102b99624bceAdam Lesinski android.support.v7.preference.R.attr.preferenceFragmentStyle, 2543fadd62b614e4a69aefe920aac640bdb629e502eJason Monk AndroidResources.ANDROID_R_PREFERENCE_FRAGMENT_STYLE), 2556904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 0); 2566904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2571fcd004668b5a9038c312e4426031027d8641353Tony Mantler mLayoutResId = a.getResourceId(R.styleable.PreferenceFragment_android_layout, mLayoutResId); 2581fcd004668b5a9038c312e4426031027d8641353Tony Mantler 2591fcd004668b5a9038c312e4426031027d8641353Tony Mantler final Drawable divider = a.getDrawable(R.styleable.PreferenceFragment_android_divider); 260301061d5655864f03f9bab0a28f7c3f2e28a0a04Tony Mantler final int dividerHeight = a.getDimensionPixelSize( 261301061d5655864f03f9bab0a28f7c3f2e28a0a04Tony Mantler R.styleable.PreferenceFragment_android_dividerHeight, -1); 2626904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2636904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler a.recycle(); 2646904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2651273d7f81a35bc244a8221a518a30e5443d24e08Tony Mantler // Need to theme the inflater to pick up the preferenceFragmentListStyle 2661273d7f81a35bc244a8221a518a30e5443d24e08Tony Mantler final TypedValue tv = new TypedValue(); 2676759b1021d8198ad1d239bb30e5a102b99624bceAdam Lesinski getActivity().getTheme().resolveAttribute( 2686759b1021d8198ad1d239bb30e5a102b99624bceAdam Lesinski android.support.v7.preference.R.attr.preferenceTheme, tv, true); 2691273d7f81a35bc244a8221a518a30e5443d24e08Tony Mantler final int theme = tv.resourceId; 2701273d7f81a35bc244a8221a518a30e5443d24e08Tony Mantler 2711273d7f81a35bc244a8221a518a30e5443d24e08Tony Mantler final Context themedContext = new ContextThemeWrapper(inflater.getContext(), theme); 2721273d7f81a35bc244a8221a518a30e5443d24e08Tony Mantler final LayoutInflater themedInflater = inflater.cloneInContext(themedContext); 2731273d7f81a35bc244a8221a518a30e5443d24e08Tony Mantler 2741273d7f81a35bc244a8221a518a30e5443d24e08Tony Mantler final View view = themedInflater.inflate(mLayoutResId, container, false); 2756904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2763fadd62b614e4a69aefe920aac640bdb629e502eJason Monk final View rawListContainer = view.findViewById(AndroidResources.ANDROID_R_LIST_CONTAINER); 2776904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (!(rawListContainer instanceof ViewGroup)) { 2783fadd62b614e4a69aefe920aac640bdb629e502eJason Monk throw new RuntimeException("Content has view with id attribute " 2793fadd62b614e4a69aefe920aac640bdb629e502eJason Monk + "'android.R.id.list_container' that is not a ViewGroup class"); 2806904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 2816904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2826904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final ViewGroup listContainer = (ViewGroup) rawListContainer; 2836904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2841273d7f81a35bc244a8221a518a30e5443d24e08Tony Mantler final RecyclerView listView = onCreateRecyclerView(themedInflater, listContainer, 2856904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler savedInstanceState); 2866904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (listView == null) { 2876904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler throw new RuntimeException("Could not create RecyclerView"); 2886904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 2896904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2906904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mList = listView; 2911fcd004668b5a9038c312e4426031027d8641353Tony Mantler 2921fcd004668b5a9038c312e4426031027d8641353Tony Mantler listView.addItemDecoration(mDividerDecoration); 2931fcd004668b5a9038c312e4426031027d8641353Tony Mantler setDivider(divider); 2941fcd004668b5a9038c312e4426031027d8641353Tony Mantler if (dividerHeight != -1) { 2951fcd004668b5a9038c312e4426031027d8641353Tony Mantler setDividerHeight(dividerHeight); 2961fcd004668b5a9038c312e4426031027d8641353Tony Mantler } 2971fcd004668b5a9038c312e4426031027d8641353Tony Mantler 2986904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler listContainer.addView(mList); 2996904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mHandler.post(mRequestFocus); 30066222008cbda61251014caf1442930a48561d25cTony Mantler 3016904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler return view; 3026904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3036904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3041fcd004668b5a9038c312e4426031027d8641353Tony Mantler /** 3051fcd004668b5a9038c312e4426031027d8641353Tony Mantler * Sets the drawable that will be drawn between each item in the list. 3061fcd004668b5a9038c312e4426031027d8641353Tony Mantler * <p> 3071fcd004668b5a9038c312e4426031027d8641353Tony Mantler * <strong>Note:</strong> If the drawable does not have an intrinsic 3081fcd004668b5a9038c312e4426031027d8641353Tony Mantler * height, you should also call {@link #setDividerHeight(int)}. 3091fcd004668b5a9038c312e4426031027d8641353Tony Mantler * 3101fcd004668b5a9038c312e4426031027d8641353Tony Mantler * @param divider the drawable to use 3111fcd004668b5a9038c312e4426031027d8641353Tony Mantler * @attr ref R.styleable#PreferenceFragment_android_divider 3121fcd004668b5a9038c312e4426031027d8641353Tony Mantler */ 3131fcd004668b5a9038c312e4426031027d8641353Tony Mantler public void setDivider(Drawable divider) { 3141fcd004668b5a9038c312e4426031027d8641353Tony Mantler mDividerDecoration.setDivider(divider); 3151fcd004668b5a9038c312e4426031027d8641353Tony Mantler } 3161fcd004668b5a9038c312e4426031027d8641353Tony Mantler 3171fcd004668b5a9038c312e4426031027d8641353Tony Mantler /** 3181fcd004668b5a9038c312e4426031027d8641353Tony Mantler * Sets the height of the divider that will be drawn between each item in the list. Calling 3191fcd004668b5a9038c312e4426031027d8641353Tony Mantler * this will override the intrinsic height as set by {@link #setDivider(Drawable)} 3201fcd004668b5a9038c312e4426031027d8641353Tony Mantler * 3211fcd004668b5a9038c312e4426031027d8641353Tony Mantler * @param height The new height of the divider in pixels. 3221fcd004668b5a9038c312e4426031027d8641353Tony Mantler * @attr ref R.styleable#PreferenceFragment_android_dividerHeight 3231fcd004668b5a9038c312e4426031027d8641353Tony Mantler */ 3241fcd004668b5a9038c312e4426031027d8641353Tony Mantler public void setDividerHeight(int height) { 3251fcd004668b5a9038c312e4426031027d8641353Tony Mantler mDividerDecoration.setDividerHeight(height); 3261fcd004668b5a9038c312e4426031027d8641353Tony Mantler } 3271fcd004668b5a9038c312e4426031027d8641353Tony Mantler 3286904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler @Override 3298f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk public void onViewCreated(View view, Bundle savedInstanceState) { 3308f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk super.onViewCreated(view, savedInstanceState); 3316904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3326904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (mHavePrefs) { 3336904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler bindPreferences(); 33466222008cbda61251014caf1442930a48561d25cTony Mantler if (mSelectPreferenceRunnable != null) { 33566222008cbda61251014caf1442930a48561d25cTony Mantler mSelectPreferenceRunnable.run(); 33666222008cbda61251014caf1442930a48561d25cTony Mantler mSelectPreferenceRunnable = null; 33766222008cbda61251014caf1442930a48561d25cTony Mantler } 3386904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3396904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3406904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mInitDone = true; 3418f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk } 3428f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk 3438f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk @Override 3448f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk public void onActivityCreated(Bundle savedInstanceState) { 3458f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk super.onActivityCreated(savedInstanceState); 3466904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3476904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (savedInstanceState != null) { 3486904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler Bundle container = savedInstanceState.getBundle(PREFERENCES_TAG); 3496904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (container != null) { 3506904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final PreferenceScreen preferenceScreen = getPreferenceScreen(); 3516904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (preferenceScreen != null) { 3526904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler preferenceScreen.restoreHierarchyState(container); 3536904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3546904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3556904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3566904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3576904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3586904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler @Override 3596904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void onStart() { 3606904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler super.onStart(); 3616904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mPreferenceManager.setOnPreferenceTreeClickListener(this); 3626904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mPreferenceManager.setOnDisplayPreferenceDialogListener(this); 3636904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3646904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3656904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler @Override 3666904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void onStop() { 3676904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler super.onStop(); 3686904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mPreferenceManager.setOnPreferenceTreeClickListener(null); 3696904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mPreferenceManager.setOnDisplayPreferenceDialogListener(null); 3706904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3716904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3726904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler @Override 3736904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void onDestroyView() { 3746904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mHandler.removeCallbacks(mRequestFocus); 3756904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mHandler.removeMessages(MSG_BIND_PREFERENCES); 3768f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk if (mHavePrefs) { 3778f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk unbindPreferences(); 3788f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk } 3798f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk mList = null; 3806904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler super.onDestroyView(); 3816904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3826904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3836904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler @Override 3846904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void onSaveInstanceState(Bundle outState) { 3856904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler super.onSaveInstanceState(outState); 3866904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3876904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final PreferenceScreen preferenceScreen = getPreferenceScreen(); 3886904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (preferenceScreen != null) { 3896904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler Bundle container = new Bundle(); 3906904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler preferenceScreen.saveHierarchyState(container); 3916904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler outState.putBundle(PREFERENCES_TAG, container); 3926904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3936904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3946904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3956904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 3966904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Returns the {@link PreferenceManager} used by this fragment. 3976904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @return The {@link PreferenceManager}. 3986904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 3996904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public PreferenceManager getPreferenceManager() { 4006904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler return mPreferenceManager; 4016904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4026904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4036904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 4046904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Sets the root of the preference hierarchy that this fragment is showing. 4056904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 4066904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy. 4076904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 4086904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void setPreferenceScreen(PreferenceScreen preferenceScreen) { 4096904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (mPreferenceManager.setPreferences(preferenceScreen) && preferenceScreen != null) { 4106904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler onUnbindPreferences(); 4116904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mHavePrefs = true; 4126904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (mInitDone) { 4136904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler postBindPreferences(); 4146904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4156904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4166904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4176904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4186904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 4196904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Gets the root of the preference hierarchy that this fragment is showing. 4206904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 4216904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @return The {@link PreferenceScreen} that is the root of the preference 4226904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * hierarchy. 4236904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 4246904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public PreferenceScreen getPreferenceScreen() { 4256904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler return mPreferenceManager.getPreferenceScreen(); 4266904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4276904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4286904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 4296904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Inflates the given XML resource and adds the preference hierarchy to the current 4306904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * preference hierarchy. 4316904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 4326904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param preferencesResId The XML resource ID to inflate. 4336904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 4346904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void addPreferencesFromResource(@XmlRes int preferencesResId) { 4356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler requirePreferenceManager(); 4366904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4376904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler setPreferenceScreen(mPreferenceManager.inflateFromResource(mStyledContext, 4386904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler preferencesResId, getPreferenceScreen())); 4396904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4406904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4416904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 4426904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Inflates the given XML resource and replaces the current preference hierarchy (if any) with 4436904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * the preference hierarchy rooted at {@code key}. 4446904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 4456904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param preferencesResId The XML resource ID to inflate. 4466904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param key The preference key of the {@link android.support.v7.preference.PreferenceScreen} 4476904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * to use as the root of the preference hierarchy, or null to use the root 4486904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link android.support.v7.preference.PreferenceScreen}. 4496904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 4506904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void setPreferencesFromResource(@XmlRes int preferencesResId, @Nullable String key) { 4516904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler requirePreferenceManager(); 4526904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4536904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final PreferenceScreen xmlRoot = mPreferenceManager.inflateFromResource(mStyledContext, 4546904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler preferencesResId, null); 4556904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4566904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final Preference root; 4576904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (key != null) { 4586904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler root = xmlRoot.findPreference(key); 4596904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (!(root instanceof PreferenceScreen)) { 4606904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler throw new IllegalArgumentException("Preference object with key " + key 4616904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler + " is not a PreferenceScreen"); 4626904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4636904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } else { 4646904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler root = xmlRoot; 4656904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4666904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4676904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler setPreferenceScreen((PreferenceScreen) root); 4686904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4696904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4706904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 4716904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@inheritDoc} 4726904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 4736904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public boolean onPreferenceTreeClick(Preference preference) { 474c4868c8a2946a038466f51875a590759092137b2Tony Mantler if (preference.getFragment() != null) { 475c4868c8a2946a038466f51875a590759092137b2Tony Mantler boolean handled = false; 47641e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler if (getCallbackFragment() instanceof OnPreferenceStartFragmentCallback) { 47741e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler handled = ((OnPreferenceStartFragmentCallback) getCallbackFragment()) 478c4868c8a2946a038466f51875a590759092137b2Tony Mantler .onPreferenceStartFragment(this, preference); 479c4868c8a2946a038466f51875a590759092137b2Tony Mantler } 480c4868c8a2946a038466f51875a590759092137b2Tony Mantler if (!handled && getActivity() instanceof OnPreferenceStartFragmentCallback){ 481c4868c8a2946a038466f51875a590759092137b2Tony Mantler handled = ((OnPreferenceStartFragmentCallback) getActivity()) 482c4868c8a2946a038466f51875a590759092137b2Tony Mantler .onPreferenceStartFragment(this, preference); 483c4868c8a2946a038466f51875a590759092137b2Tony Mantler } 484c4868c8a2946a038466f51875a590759092137b2Tony Mantler return handled; 4856904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4866904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler return false; 4876904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4886904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4896904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 4906904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Called by 4916904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link android.support.v7.preference.PreferenceScreen#onClick()} in order to navigate to a 4926904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * new screen of preferences. Calls 4936904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link PreferenceFragment.OnPreferenceStartScreenCallback#onPreferenceStartScreen} 494c4868c8a2946a038466f51875a590759092137b2Tony Mantler * if the target fragment or containing activity implements 4956904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link PreferenceFragment.OnPreferenceStartScreenCallback}. 4966904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param preferenceScreen The {@link android.support.v7.preference.PreferenceScreen} to 4976904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * navigate to. 4986904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 4996904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler @Override 5006904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void onNavigateToScreen(PreferenceScreen preferenceScreen) { 501bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler boolean handled = false; 50241e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler if (getCallbackFragment() instanceof OnPreferenceStartScreenCallback) { 50341e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler handled = ((OnPreferenceStartScreenCallback) getCallbackFragment()) 504bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler .onPreferenceStartScreen(this, preferenceScreen); 505bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler } 506bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler if (!handled && getActivity() instanceof OnPreferenceStartScreenCallback) { 507bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler ((OnPreferenceStartScreenCallback) getActivity()) 508bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler .onPreferenceStartScreen(this, preferenceScreen); 5096904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 5106904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 5116904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 5126904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 5136904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Finds a {@link Preference} based on its key. 5146904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 5156904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param key The key of the preference to retrieve. 5166904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @return The {@link Preference} with the key, or null. 5176904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @see android.support.v7.preference.PreferenceGroup#findPreference(CharSequence) 5186904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 5196904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public Preference findPreference(CharSequence key) { 5206904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (mPreferenceManager == null) { 5216904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler return null; 5226904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 5236904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler return mPreferenceManager.findPreference(key); 5246904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 5256904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 5266904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private void requirePreferenceManager() { 5276904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (mPreferenceManager == null) { 5286904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler throw new RuntimeException("This should be called after super.onCreate."); 5296904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 5306904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 5316904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 5326904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private void postBindPreferences() { 5336904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) return; 5346904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget(); 5356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 5366904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 5376904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private void bindPreferences() { 5386904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final PreferenceScreen preferenceScreen = getPreferenceScreen(); 5396904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (preferenceScreen != null) { 54053b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler getListView().setAdapter(onCreateAdapter(preferenceScreen)); 541e61b4475e1837034d8926593aff9d35f8dfaebe2Tony Mantler preferenceScreen.onAttached(); 5426904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 5436904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler onBindPreferences(); 5446904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 5456904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 5468f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk private void unbindPreferences() { 5478f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk final PreferenceScreen preferenceScreen = getPreferenceScreen(); 5488f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk if (preferenceScreen != null) { 5498f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk preferenceScreen.onDetached(); 5508f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk } 5518f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk onUnbindPreferences(); 5528f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk } 5538f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk 5546904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** @hide */ 5556904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler protected void onBindPreferences() { 5566904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 5576904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 5586904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** @hide */ 5596904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler protected void onUnbindPreferences() { 5606904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 5616904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 5626904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public final RecyclerView getListView() { 5636904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler return mList; 5646904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 5656904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 5666904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 5676904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Creates the {@link android.support.v7.widget.RecyclerView} used to display the preferences. 5686904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Subclasses may override this to return a customized 5696904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link android.support.v7.widget.RecyclerView}. 5706904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param inflater The LayoutInflater object that can be used to inflate the 5716904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link android.support.v7.widget.RecyclerView}. 5726904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param parent The parent {@link android.view.View} that the RecyclerView will be attached to. 5736904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * This method should not add the view itself, but this can be used to generate 5746904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * the LayoutParams of the view. 5756904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param savedInstanceState If non-null, this view is being re-constructed from a previous 5766904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * saved state as given here 5776904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @return A new RecyclerView object to be placed into the view hierarchy 5786904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 5796904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent, 5806904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler Bundle savedInstanceState) { 5816904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler RecyclerView recyclerView = (RecyclerView) inflater 5826759b1021d8198ad1d239bb30e5a102b99624bceAdam Lesinski .inflate(android.support.v7.preference.R.layout.preference_recyclerview, 5836759b1021d8198ad1d239bb30e5a102b99624bceAdam Lesinski parent, false); 5846904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 5856904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler recyclerView.setLayoutManager(onCreateLayoutManager()); 5861553af7799b550e0821a5e579db0bccf1f0835b8Steven Dao recyclerView.setAccessibilityDelegateCompat( 5871553af7799b550e0821a5e579db0bccf1f0835b8Steven Dao new PreferenceRecyclerViewAccessibilityDelegate(recyclerView)); 5886904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 5896904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler return recyclerView; 5906904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 5916904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 5926904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 5936904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Called from {@link #onCreateRecyclerView} to create the 5946904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link android.support.v7.widget.RecyclerView.LayoutManager} for the created 5956904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link android.support.v7.widget.RecyclerView}. 5966904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @return A new {@link android.support.v7.widget.RecyclerView.LayoutManager} instance. 5976904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 5986904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public RecyclerView.LayoutManager onCreateLayoutManager() { 5996904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler return new LinearLayoutManager(getActivity()); 6006904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 6016904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 6026904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 60353b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler * Creates the root adapter. 60453b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler * 60553b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler * @param preferenceScreen Preference screen object to create the adapter for. 60653b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler * @return An adapter that contains the preferences contained in this {@link PreferenceScreen}. 60753b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler */ 60853b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) { 60953b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler return new PreferenceGroupAdapter(preferenceScreen); 61053b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler } 61153b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler 61253b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler /** 6136904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Called when a preference in the tree requests to display a dialog. Subclasses should 6146904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * override this method to display custom dialogs or to handle dialogs for custom preference 6156904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * classes. 6166904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 6176904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param preference The Preference object requesting the dialog. 6186904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 6196904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler @Override 6206904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void onDisplayPreferenceDialog(Preference preference) { 621bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler 622bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler boolean handled = false; 62341e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler if (getCallbackFragment() instanceof OnPreferenceDisplayDialogCallback) { 62441e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler handled = ((OnPreferenceDisplayDialogCallback) getCallbackFragment()) 625bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler .onPreferenceDisplayDialog(this, preference); 626bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler } 627bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler if (!handled && getActivity() instanceof OnPreferenceDisplayDialogCallback) { 628bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler handled = ((OnPreferenceDisplayDialogCallback) getActivity()) 629bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler .onPreferenceDisplayDialog(this, preference); 630bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler } 631bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler 632bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler if (handled) { 633bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler return; 634bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler } 635bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler 6366904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler // check if dialog is already showing 6376904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (getFragmentManager().findFragmentByTag(DIALOG_FRAGMENT_TAG) != null) { 6386904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler return; 6396904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 6406904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 6416904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final DialogFragment f; 6426904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (preference instanceof EditTextPreference) { 6436904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler f = EditTextPreferenceDialogFragment.newInstance(preference.getKey()); 6446904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } else if (preference instanceof ListPreference) { 6456904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler f = ListPreferenceDialogFragment.newInstance(preference.getKey()); 6460112bacf4aa212f4d0da45594a88694f295ae56cTony Mantler } else if (preference instanceof MultiSelectListPreference) { 6470112bacf4aa212f4d0da45594a88694f295ae56cTony Mantler f = MultiSelectListPreferenceDialogFragment.newInstance(preference.getKey()); 6486904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } else { 6496904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler throw new IllegalArgumentException("Tried to display dialog for unknown " + 6506904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler "preference type. Did you forget to override onDisplayPreferenceDialog()?"); 6516904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 6526904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler f.setTargetFragment(this, 0); 6536904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler f.show(getFragmentManager(), DIALOG_FRAGMENT_TAG); 6546904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 6556904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 65641e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler /** 65741e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler * Basically a wrapper for getParentFragment which is v17+. Used by the leanback preference lib. 65841e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler * @return Fragment to possibly use as a callback 65941e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler * @hide 66041e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler */ 66141e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler public Fragment getCallbackFragment() { 66241e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler return null; 66341e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler } 6641fcd004668b5a9038c312e4426031027d8641353Tony Mantler 66566222008cbda61251014caf1442930a48561d25cTony Mantler public void scrollToPreference(final String key) { 66666222008cbda61251014caf1442930a48561d25cTony Mantler scrollToPreferenceInternal(null, key); 66766222008cbda61251014caf1442930a48561d25cTony Mantler } 66866222008cbda61251014caf1442930a48561d25cTony Mantler 66966222008cbda61251014caf1442930a48561d25cTony Mantler public void scrollToPreference(final Preference preference) { 67066222008cbda61251014caf1442930a48561d25cTony Mantler scrollToPreferenceInternal(preference, null); 67166222008cbda61251014caf1442930a48561d25cTony Mantler } 67266222008cbda61251014caf1442930a48561d25cTony Mantler 67366222008cbda61251014caf1442930a48561d25cTony Mantler private void scrollToPreferenceInternal(final Preference preference, final String key) { 67466222008cbda61251014caf1442930a48561d25cTony Mantler final Runnable r = new Runnable() { 67566222008cbda61251014caf1442930a48561d25cTony Mantler @Override 67666222008cbda61251014caf1442930a48561d25cTony Mantler public void run() { 67766222008cbda61251014caf1442930a48561d25cTony Mantler final RecyclerView.Adapter adapter = mList.getAdapter(); 67866222008cbda61251014caf1442930a48561d25cTony Mantler if (!(adapter instanceof 67966222008cbda61251014caf1442930a48561d25cTony Mantler PreferenceGroup.PreferencePositionCallback)) { 68066222008cbda61251014caf1442930a48561d25cTony Mantler if (adapter != null) { 68166222008cbda61251014caf1442930a48561d25cTony Mantler throw new IllegalStateException("Adapter must implement " 68266222008cbda61251014caf1442930a48561d25cTony Mantler + "PreferencePositionCallback"); 68366222008cbda61251014caf1442930a48561d25cTony Mantler } else { 68466222008cbda61251014caf1442930a48561d25cTony Mantler // Adapter was set to null, so don't scroll I guess? 68566222008cbda61251014caf1442930a48561d25cTony Mantler return; 68666222008cbda61251014caf1442930a48561d25cTony Mantler } 68766222008cbda61251014caf1442930a48561d25cTony Mantler } 68866222008cbda61251014caf1442930a48561d25cTony Mantler final int position; 68966222008cbda61251014caf1442930a48561d25cTony Mantler if (preference != null) { 69066222008cbda61251014caf1442930a48561d25cTony Mantler position = ((PreferenceGroup.PreferencePositionCallback) adapter) 69166222008cbda61251014caf1442930a48561d25cTony Mantler .getPreferenceAdapterPosition(preference); 69266222008cbda61251014caf1442930a48561d25cTony Mantler } else { 69366222008cbda61251014caf1442930a48561d25cTony Mantler position = ((PreferenceGroup.PreferencePositionCallback) adapter) 69466222008cbda61251014caf1442930a48561d25cTony Mantler .getPreferenceAdapterPosition(key); 69566222008cbda61251014caf1442930a48561d25cTony Mantler } 69666222008cbda61251014caf1442930a48561d25cTony Mantler if (position != RecyclerView.NO_POSITION) { 69766222008cbda61251014caf1442930a48561d25cTony Mantler mList.scrollToPosition(position); 69866222008cbda61251014caf1442930a48561d25cTony Mantler } else { 69966222008cbda61251014caf1442930a48561d25cTony Mantler // Item not found, wait for an update and try again 70066222008cbda61251014caf1442930a48561d25cTony Mantler adapter.registerAdapterDataObserver( 70166222008cbda61251014caf1442930a48561d25cTony Mantler new ScrollToPreferenceObserver(adapter, mList, preference, key)); 70266222008cbda61251014caf1442930a48561d25cTony Mantler } 70366222008cbda61251014caf1442930a48561d25cTony Mantler } 70466222008cbda61251014caf1442930a48561d25cTony Mantler }; 70566222008cbda61251014caf1442930a48561d25cTony Mantler if (mList == null) { 70666222008cbda61251014caf1442930a48561d25cTony Mantler mSelectPreferenceRunnable = r; 70766222008cbda61251014caf1442930a48561d25cTony Mantler } else { 70866222008cbda61251014caf1442930a48561d25cTony Mantler r.run(); 70966222008cbda61251014caf1442930a48561d25cTony Mantler } 71066222008cbda61251014caf1442930a48561d25cTony Mantler } 71166222008cbda61251014caf1442930a48561d25cTony Mantler 71266222008cbda61251014caf1442930a48561d25cTony Mantler private static class ScrollToPreferenceObserver extends RecyclerView.AdapterDataObserver { 71366222008cbda61251014caf1442930a48561d25cTony Mantler private final RecyclerView.Adapter mAdapter; 71466222008cbda61251014caf1442930a48561d25cTony Mantler private final RecyclerView mList; 71566222008cbda61251014caf1442930a48561d25cTony Mantler private final Preference mPreference; 71666222008cbda61251014caf1442930a48561d25cTony Mantler private final String mKey; 71766222008cbda61251014caf1442930a48561d25cTony Mantler 71866222008cbda61251014caf1442930a48561d25cTony Mantler public ScrollToPreferenceObserver(RecyclerView.Adapter adapter, RecyclerView list, 71966222008cbda61251014caf1442930a48561d25cTony Mantler Preference preference, String key) { 72066222008cbda61251014caf1442930a48561d25cTony Mantler mAdapter = adapter; 72166222008cbda61251014caf1442930a48561d25cTony Mantler mList = list; 72266222008cbda61251014caf1442930a48561d25cTony Mantler mPreference = preference; 72366222008cbda61251014caf1442930a48561d25cTony Mantler mKey = key; 72466222008cbda61251014caf1442930a48561d25cTony Mantler } 72566222008cbda61251014caf1442930a48561d25cTony Mantler 72666222008cbda61251014caf1442930a48561d25cTony Mantler private void scrollToPreference() { 72766222008cbda61251014caf1442930a48561d25cTony Mantler mAdapter.unregisterAdapterDataObserver(this); 72866222008cbda61251014caf1442930a48561d25cTony Mantler final int position; 72966222008cbda61251014caf1442930a48561d25cTony Mantler if (mPreference != null) { 73066222008cbda61251014caf1442930a48561d25cTony Mantler position = ((PreferenceGroup.PreferencePositionCallback) mAdapter) 73166222008cbda61251014caf1442930a48561d25cTony Mantler .getPreferenceAdapterPosition(mPreference); 73266222008cbda61251014caf1442930a48561d25cTony Mantler } else { 73366222008cbda61251014caf1442930a48561d25cTony Mantler position = ((PreferenceGroup.PreferencePositionCallback) mAdapter) 73466222008cbda61251014caf1442930a48561d25cTony Mantler .getPreferenceAdapterPosition(mKey); 73566222008cbda61251014caf1442930a48561d25cTony Mantler } 73666222008cbda61251014caf1442930a48561d25cTony Mantler if (position != RecyclerView.NO_POSITION) { 73766222008cbda61251014caf1442930a48561d25cTony Mantler mList.scrollToPosition(position); 73866222008cbda61251014caf1442930a48561d25cTony Mantler } 73966222008cbda61251014caf1442930a48561d25cTony Mantler } 74066222008cbda61251014caf1442930a48561d25cTony Mantler 74166222008cbda61251014caf1442930a48561d25cTony Mantler @Override 74266222008cbda61251014caf1442930a48561d25cTony Mantler public void onChanged() { 74366222008cbda61251014caf1442930a48561d25cTony Mantler scrollToPreference(); 74466222008cbda61251014caf1442930a48561d25cTony Mantler } 74566222008cbda61251014caf1442930a48561d25cTony Mantler 74666222008cbda61251014caf1442930a48561d25cTony Mantler @Override 74766222008cbda61251014caf1442930a48561d25cTony Mantler public void onItemRangeChanged(int positionStart, int itemCount) { 74866222008cbda61251014caf1442930a48561d25cTony Mantler scrollToPreference(); 74966222008cbda61251014caf1442930a48561d25cTony Mantler } 75066222008cbda61251014caf1442930a48561d25cTony Mantler 75166222008cbda61251014caf1442930a48561d25cTony Mantler @Override 75266222008cbda61251014caf1442930a48561d25cTony Mantler public void onItemRangeChanged(int positionStart, int itemCount, Object payload) { 75366222008cbda61251014caf1442930a48561d25cTony Mantler scrollToPreference(); 75466222008cbda61251014caf1442930a48561d25cTony Mantler } 75566222008cbda61251014caf1442930a48561d25cTony Mantler 75666222008cbda61251014caf1442930a48561d25cTony Mantler @Override 75766222008cbda61251014caf1442930a48561d25cTony Mantler public void onItemRangeInserted(int positionStart, int itemCount) { 75866222008cbda61251014caf1442930a48561d25cTony Mantler scrollToPreference(); 75966222008cbda61251014caf1442930a48561d25cTony Mantler } 76066222008cbda61251014caf1442930a48561d25cTony Mantler 76166222008cbda61251014caf1442930a48561d25cTony Mantler @Override 76266222008cbda61251014caf1442930a48561d25cTony Mantler public void onItemRangeRemoved(int positionStart, int itemCount) { 76366222008cbda61251014caf1442930a48561d25cTony Mantler scrollToPreference(); 76466222008cbda61251014caf1442930a48561d25cTony Mantler } 76566222008cbda61251014caf1442930a48561d25cTony Mantler 76666222008cbda61251014caf1442930a48561d25cTony Mantler @Override 76766222008cbda61251014caf1442930a48561d25cTony Mantler public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { 76866222008cbda61251014caf1442930a48561d25cTony Mantler scrollToPreference(); 76966222008cbda61251014caf1442930a48561d25cTony Mantler } 77066222008cbda61251014caf1442930a48561d25cTony Mantler } 77166222008cbda61251014caf1442930a48561d25cTony Mantler 7721fcd004668b5a9038c312e4426031027d8641353Tony Mantler private class DividerDecoration extends RecyclerView.ItemDecoration { 7731fcd004668b5a9038c312e4426031027d8641353Tony Mantler 7741fcd004668b5a9038c312e4426031027d8641353Tony Mantler private Drawable mDivider; 7751fcd004668b5a9038c312e4426031027d8641353Tony Mantler private int mDividerHeight; 7761fcd004668b5a9038c312e4426031027d8641353Tony Mantler 7771fcd004668b5a9038c312e4426031027d8641353Tony Mantler @Override 7781fcd004668b5a9038c312e4426031027d8641353Tony Mantler public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { 7791fcd004668b5a9038c312e4426031027d8641353Tony Mantler if (mDivider == null) { 7801fcd004668b5a9038c312e4426031027d8641353Tony Mantler return; 7811fcd004668b5a9038c312e4426031027d8641353Tony Mantler } 7821fcd004668b5a9038c312e4426031027d8641353Tony Mantler final int childCount = parent.getChildCount(); 7831fcd004668b5a9038c312e4426031027d8641353Tony Mantler final int width = parent.getWidth(); 7841fcd004668b5a9038c312e4426031027d8641353Tony Mantler for (int childViewIndex = 0; childViewIndex < childCount; childViewIndex++) { 7851fcd004668b5a9038c312e4426031027d8641353Tony Mantler final View view = parent.getChildAt(childViewIndex); 7861fcd004668b5a9038c312e4426031027d8641353Tony Mantler if (shouldDrawDividerBelow(view, parent)) { 7871fcd004668b5a9038c312e4426031027d8641353Tony Mantler int top = (int) ViewCompat.getY(view) + view.getHeight(); 7881fcd004668b5a9038c312e4426031027d8641353Tony Mantler mDivider.setBounds(0, top, width, top + mDividerHeight); 7891fcd004668b5a9038c312e4426031027d8641353Tony Mantler mDivider.draw(c); 7901fcd004668b5a9038c312e4426031027d8641353Tony Mantler } 7911fcd004668b5a9038c312e4426031027d8641353Tony Mantler } 7921fcd004668b5a9038c312e4426031027d8641353Tony Mantler } 7931fcd004668b5a9038c312e4426031027d8641353Tony Mantler 7941fcd004668b5a9038c312e4426031027d8641353Tony Mantler @Override 7951fcd004668b5a9038c312e4426031027d8641353Tony Mantler public void getItemOffsets(Rect outRect, View view, RecyclerView parent, 7961fcd004668b5a9038c312e4426031027d8641353Tony Mantler RecyclerView.State state) { 7971fcd004668b5a9038c312e4426031027d8641353Tony Mantler if (shouldDrawDividerBelow(view, parent)) { 7981fcd004668b5a9038c312e4426031027d8641353Tony Mantler outRect.bottom = mDividerHeight; 7991fcd004668b5a9038c312e4426031027d8641353Tony Mantler } 8001fcd004668b5a9038c312e4426031027d8641353Tony Mantler } 8011fcd004668b5a9038c312e4426031027d8641353Tony Mantler 8021fcd004668b5a9038c312e4426031027d8641353Tony Mantler private boolean shouldDrawDividerBelow(View view, RecyclerView parent) { 803446e2ab0a44e2515218540f38672987188287aa2Maurice Lam final RecyclerView.ViewHolder holder = parent.getChildViewHolder(view); 804446e2ab0a44e2515218540f38672987188287aa2Maurice Lam final boolean dividerAllowedBelow = holder instanceof PreferenceViewHolder 805446e2ab0a44e2515218540f38672987188287aa2Maurice Lam && ((PreferenceViewHolder) holder).isDividerAllowedBelow(); 806446e2ab0a44e2515218540f38672987188287aa2Maurice Lam if (!dividerAllowedBelow) { 807446e2ab0a44e2515218540f38672987188287aa2Maurice Lam return false; 808446e2ab0a44e2515218540f38672987188287aa2Maurice Lam } 8091fcd004668b5a9038c312e4426031027d8641353Tony Mantler boolean nextAllowed = true; 8101fcd004668b5a9038c312e4426031027d8641353Tony Mantler int index = parent.indexOfChild(view); 8111fcd004668b5a9038c312e4426031027d8641353Tony Mantler if (index < parent.getChildCount() - 1) { 8121fcd004668b5a9038c312e4426031027d8641353Tony Mantler final View nextView = parent.getChildAt(index + 1); 813446e2ab0a44e2515218540f38672987188287aa2Maurice Lam final RecyclerView.ViewHolder nextHolder = parent.getChildViewHolder(nextView); 814446e2ab0a44e2515218540f38672987188287aa2Maurice Lam nextAllowed = nextHolder instanceof PreferenceViewHolder 815446e2ab0a44e2515218540f38672987188287aa2Maurice Lam && ((PreferenceViewHolder) nextHolder).isDividerAllowedAbove(); 8161fcd004668b5a9038c312e4426031027d8641353Tony Mantler } 817446e2ab0a44e2515218540f38672987188287aa2Maurice Lam return nextAllowed; 8181fcd004668b5a9038c312e4426031027d8641353Tony Mantler } 8191fcd004668b5a9038c312e4426031027d8641353Tony Mantler 8201fcd004668b5a9038c312e4426031027d8641353Tony Mantler public void setDivider(Drawable divider) { 8211fcd004668b5a9038c312e4426031027d8641353Tony Mantler if (divider != null) { 8221fcd004668b5a9038c312e4426031027d8641353Tony Mantler mDividerHeight = divider.getIntrinsicHeight(); 8231fcd004668b5a9038c312e4426031027d8641353Tony Mantler } else { 8241fcd004668b5a9038c312e4426031027d8641353Tony Mantler mDividerHeight = 0; 8251fcd004668b5a9038c312e4426031027d8641353Tony Mantler } 8261fcd004668b5a9038c312e4426031027d8641353Tony Mantler mDivider = divider; 8271fcd004668b5a9038c312e4426031027d8641353Tony Mantler mList.invalidateItemDecorations(); 8281fcd004668b5a9038c312e4426031027d8641353Tony Mantler } 8291fcd004668b5a9038c312e4426031027d8641353Tony Mantler 8301fcd004668b5a9038c312e4426031027d8641353Tony Mantler public void setDividerHeight(int dividerHeight) { 8311fcd004668b5a9038c312e4426031027d8641353Tony Mantler mDividerHeight = dividerHeight; 8321fcd004668b5a9038c312e4426031027d8641353Tony Mantler mList.invalidateItemDecorations(); 8331fcd004668b5a9038c312e4426031027d8641353Tony Mantler } 8341fcd004668b5a9038c312e4426031027d8641353Tony Mantler } 8356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler} 836