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; 236904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.os.Bundle; 246904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.os.Handler; 256904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.os.Message; 266904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.annotation.Nullable; 276904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.annotation.XmlRes; 286904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.v7.preference.DialogPreference; 296904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.v7.preference.EditTextPreference; 306904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.v7.preference.ListPreference; 316904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.v7.preference.Preference; 3253b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantlerimport android.support.v7.preference.PreferenceGroupAdapter; 336904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.v7.preference.PreferenceManager; 346904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.v7.preference.PreferenceScreen; 356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.v7.widget.LinearLayoutManager; 366904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.v7.widget.RecyclerView; 376904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.util.TypedValue; 386904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.view.ContextThemeWrapper; 396904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.view.LayoutInflater; 406904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.view.View; 416904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.view.ViewGroup; 426904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 436904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler/** 446904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Shows a hierarchy of {@link Preference} objects as 456904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * lists. These preferences will 466904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * automatically save to {@link android.content.SharedPreferences} as the user interacts with 476904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * them. To retrieve an instance of {@link android.content.SharedPreferences} that the 486904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * preference hierarchy in this fragment will use, call 496904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link PreferenceManager#getDefaultSharedPreferences(android.content.Context)} 506904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * with a context in the same package as this fragment. 516904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <p> 526904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Furthermore, the preferences shown will follow the visual style of system 536904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * preferences. It is easy to create a hierarchy of preferences (that can be 546904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * shown on multiple screens) via XML. For these reasons, it is recommended to 556904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * use this fragment (as a superclass) to deal with preferences in applications. 566904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <p> 576904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * A {@link PreferenceScreen} object should be at the top of the preference 586904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * hierarchy. Furthermore, subsequent {@link PreferenceScreen} in the hierarchy 596904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * denote a screen break--that is the preferences contained within subsequent 606904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link PreferenceScreen} should be shown on another screen. The preference 616904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * framework handles showing these other screens from the preference hierarchy. 626904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <p> 636904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * The preference hierarchy can be formed in multiple ways: 646904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <li> From an XML file specifying the hierarchy 656904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <li> From different {@link android.app.Activity Activities} that each specify its own 666904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * preferences in an XML file via {@link android.app.Activity} meta-data 676904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <li> From an object hierarchy rooted with {@link PreferenceScreen} 686904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <p> 696904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * To inflate from XML, use the {@link #addPreferencesFromResource(int)}. The 706904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * root element should be a {@link PreferenceScreen}. Subsequent elements can point 716904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * to actual {@link Preference} subclasses. As mentioned above, subsequent 726904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link PreferenceScreen} in the hierarchy will result in the screen break. 736904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <p> 746904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * To specify an object hierarchy rooted with {@link PreferenceScreen}, use 756904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link #setPreferenceScreen(PreferenceScreen)}. 766904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <p> 776904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * As a convenience, this fragment implements a click listener for any 786904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * preference in the current hierarchy, see 796904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link #onPreferenceTreeClick(Preference)}. 806904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 816904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <div class="special reference"> 826904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <h3>Developer Guides</h3> 836904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <p>For information about using {@code PreferenceFragment}, 846904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * read the <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a> 856904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * guide.</p> 866904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * </div> 876904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 886904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <a name="SampleCode"></a> 896904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <h3>Sample Code</h3> 906904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 916904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <p>The following sample code shows a simple preference fragment that is 926904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * populated from a resource. The resource it loads is:</p> 936904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 946904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@sample development/samples/ApiDemos/res/xml/preferences.xml preferences} 956904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 966904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <p>The fragment implementation itself simply populates the preferences 976904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * when created. Note that the preferences framework takes care of loading 986904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * the current values out of the app preferences and writing them when changed:</p> 996904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 1006904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@sample development/samples/ApiDemos/src/com/example/android/apis/preference/FragmentPreferences.java 1016904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * fragment} 1026904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 1036904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @see Preference 1046904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @see PreferenceScreen 1056904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 1066904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerpublic abstract class PreferenceFragment extends Fragment implements 1076904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler PreferenceManager.OnPreferenceTreeClickListener, 1086904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler PreferenceManager.OnDisplayPreferenceDialogListener, 1096904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler PreferenceManager.OnNavigateToScreenListener, 1106904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler DialogPreference.TargetFragment { 1116904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1126904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 1136904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Fragment argument used to specify the tag of the desired root 1146904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link android.support.v7.preference.PreferenceScreen} object. 1156904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 1166904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public static final String ARG_PREFERENCE_ROOT = 1176904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler "android.support.v7.preference.PreferenceFragmentCompat.PREFERENCE_ROOT"; 1186904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1196904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private static final String PREFERENCES_TAG = "android:preferences"; 1206904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1216904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private static final String DIALOG_FRAGMENT_TAG = 1226904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler "android.support.v14.preference.PreferenceFragment.DIALOG"; 1236904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1246904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private PreferenceManager mPreferenceManager; 1256904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private RecyclerView mList; 1266904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private boolean mHavePrefs; 1276904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private boolean mInitDone; 1286904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1296904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private Context mStyledContext; 1306904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1316904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private int mLayoutResId = R.layout.preference_list_fragment; 1326904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1336904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 1346904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * The starting request code given out to preference framework. 1356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 1366904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private static final int FIRST_REQUEST_CODE = 100; 1376904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1386904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private static final int MSG_BIND_PREFERENCES = 1; 1396904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private Handler mHandler = new Handler() { 1406904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler @Override 1416904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void handleMessage(Message msg) { 1426904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler switch (msg.what) { 1436904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1446904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler case MSG_BIND_PREFERENCES: 1456904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler bindPreferences(); 1466904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler break; 1476904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 1486904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 1496904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler }; 1506904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1516904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final private Runnable mRequestFocus = new Runnable() { 1526904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void run() { 1536904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mList.focusableViewAvailable(mList); 1546904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 1556904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler }; 1566904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1576904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 1586904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Interface that PreferenceFragment's containing activity should 1596904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * implement to be able to process preference items that wish to 1606904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * switch to a specified fragment. 1616904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 1626904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public interface OnPreferenceStartFragmentCallback { 1636904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 1646904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Called when the user has clicked on a Preference that has 1656904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * a fragment class name associated with it. The implementation 16653b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler * should instantiate and switch to an instance of the given 1676904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * fragment. 168bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler * @param caller The fragment requesting navigation. 169bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler * @param pref The preference requesting the fragment. 170bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler * @return true if the fragment creation has been handled 1716904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 1726904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref); 1736904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 1746904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 1756904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 1766904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Interface that PreferenceFragment's containing activity should 1776904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * implement to be able to process preference items that wish to 1786904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * switch to a new screen of preferences. 1796904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 1806904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public interface OnPreferenceStartScreenCallback { 1816904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 1826904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Called when the user has clicked on a PreferenceScreen item in order to navigate to a new 1836904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * screen of preferences. 1846904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param caller The fragment requesting navigation. 1856904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param pref The preference screen to navigate to. 186bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler * @return true if the screen navigation has been handled 1876904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 1886904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler boolean onPreferenceStartScreen(PreferenceFragment caller, PreferenceScreen pref); 1896904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 1906904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 191bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler public interface OnPreferenceDisplayDialogCallback { 192bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler 193bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler /** 194bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler * 195bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler * @param caller The fragment containing the preference requesting the dialog. 196bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler * @param pref The preference requesting the dialog. 197bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler * @return true if the dialog creation has been handled. 198bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler */ 199bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler boolean onPreferenceDisplayDialog(PreferenceFragment caller, Preference pref); 200bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler } 201bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler 2026904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler @Override 2036904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void onCreate(Bundle savedInstanceState) { 2046904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler super.onCreate(savedInstanceState); 2056904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final TypedValue tv = new TypedValue(); 2066904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler getActivity().getTheme().resolveAttribute(R.attr.preferenceTheme, tv, true); 2076904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final int theme = tv.resourceId; 2086904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (theme <= 0) { 2096904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler throw new IllegalStateException("Must specify preferenceTheme in theme"); 2106904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 2116904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mStyledContext = new ContextThemeWrapper(getActivity(), theme); 2126904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2136904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mPreferenceManager = new PreferenceManager(mStyledContext); 2146904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mPreferenceManager.setOnNavigateToScreenListener(this); 2156904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final Bundle args = getArguments(); 2166904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final String rootKey; 2176904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (args != null) { 2186904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler rootKey = getArguments().getString(ARG_PREFERENCE_ROOT); 2196904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } else { 2206904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler rootKey = null; 2216904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 2226904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler onCreatePreferences(savedInstanceState, rootKey); 2236904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 2246904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2256904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 2266904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Called during {@link #onCreate(Bundle)} to supply the preferences for this fragment. 2276904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Subclasses are expected to call {@link #setPreferenceScreen(PreferenceScreen)} either 2286904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * directly or via helper methods such as {@link #addPreferencesFromResource(int)}. 2296904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 2306904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param savedInstanceState If the fragment is being re-created from 2316904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * a previous saved state, this is the state. 2326904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param rootKey If non-null, this preference fragment should be rooted at the 2336904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link android.support.v7.preference.PreferenceScreen} with this key. 2346904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 2356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public abstract void onCreatePreferences(Bundle savedInstanceState, String rootKey); 2366904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2376904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler @Override 2386904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public View onCreateView(LayoutInflater inflater, ViewGroup container, 2396904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler Bundle savedInstanceState) { 2406904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2416904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler TypedArray a = mStyledContext.obtainStyledAttributes(null, 2426904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler R.styleable.PreferenceFragmentCompat, 2436904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler R.attr.preferenceFragmentStyle, 2446904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 0); 2456904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2466904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mLayoutResId = a.getResourceId(R.styleable.PreferenceFragmentCompat_layout, 2476904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mLayoutResId); 2486904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2496904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler a.recycle(); 2506904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2516904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final View view = inflater.inflate(mLayoutResId, container, false); 2526904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2536904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final View rawListContainer = view.findViewById(R.id.list_container); 2546904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (!(rawListContainer instanceof ViewGroup)) { 2556904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler throw new RuntimeException("Content has view with id attribute 'R.id.list_container' " 2566904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler + "that is not a ViewGroup class"); 2576904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 2586904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2596904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final ViewGroup listContainer = (ViewGroup) rawListContainer; 2606904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2616904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final RecyclerView listView = onCreateRecyclerView(inflater, listContainer, 2626904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler savedInstanceState); 2636904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (listView == null) { 2646904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler throw new RuntimeException("Could not create RecyclerView"); 2656904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 2666904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2676904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mList = listView; 2686904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler listContainer.addView(mList); 2696904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mHandler.post(mRequestFocus); 2706904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler return view; 2716904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 2726904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2736904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler @Override 2746904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void onActivityCreated(Bundle savedInstanceState) { 2756904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler super.onActivityCreated(savedInstanceState); 2766904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2776904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (mHavePrefs) { 2786904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler bindPreferences(); 2796904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 2806904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2816904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mInitDone = true; 2826904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2836904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (savedInstanceState != null) { 2846904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler Bundle container = savedInstanceState.getBundle(PREFERENCES_TAG); 2856904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (container != null) { 2866904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final PreferenceScreen preferenceScreen = getPreferenceScreen(); 2876904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (preferenceScreen != null) { 2886904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler preferenceScreen.restoreHierarchyState(container); 2896904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 2906904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 2916904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 2926904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 2936904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 2946904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler @Override 2956904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void onStart() { 2966904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler super.onStart(); 2976904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mPreferenceManager.setOnPreferenceTreeClickListener(this); 2986904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mPreferenceManager.setOnDisplayPreferenceDialogListener(this); 2996904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3006904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3016904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler @Override 3026904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void onStop() { 3036904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler super.onStop(); 3046904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mPreferenceManager.setOnPreferenceTreeClickListener(null); 3056904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mPreferenceManager.setOnDisplayPreferenceDialogListener(null); 3066904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3076904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3086904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler @Override 3096904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void onDestroyView() { 3106904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mList = null; 3116904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mHandler.removeCallbacks(mRequestFocus); 3126904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mHandler.removeMessages(MSG_BIND_PREFERENCES); 3136904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler super.onDestroyView(); 3146904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3156904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3166904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler @Override 3176904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void onSaveInstanceState(Bundle outState) { 3186904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler super.onSaveInstanceState(outState); 3196904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3206904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final PreferenceScreen preferenceScreen = getPreferenceScreen(); 3216904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (preferenceScreen != null) { 3226904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler Bundle container = new Bundle(); 3236904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler preferenceScreen.saveHierarchyState(container); 3246904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler outState.putBundle(PREFERENCES_TAG, container); 3256904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3266904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3276904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3286904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 3296904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Returns the {@link PreferenceManager} used by this fragment. 3306904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @return The {@link PreferenceManager}. 3316904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 3326904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public PreferenceManager getPreferenceManager() { 3336904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler return mPreferenceManager; 3346904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3366904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 3376904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Sets the root of the preference hierarchy that this fragment is showing. 3386904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 3396904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy. 3406904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 3416904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void setPreferenceScreen(PreferenceScreen preferenceScreen) { 3426904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (mPreferenceManager.setPreferences(preferenceScreen) && preferenceScreen != null) { 3436904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler onUnbindPreferences(); 3446904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mHavePrefs = true; 3456904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (mInitDone) { 3466904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler postBindPreferences(); 3476904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3486904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3496904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3506904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3516904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 3526904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Gets the root of the preference hierarchy that this fragment is showing. 3536904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 3546904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @return The {@link PreferenceScreen} that is the root of the preference 3556904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * hierarchy. 3566904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 3576904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public PreferenceScreen getPreferenceScreen() { 3586904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler return mPreferenceManager.getPreferenceScreen(); 3596904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3606904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3616904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 3626904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Inflates the given XML resource and adds the preference hierarchy to the current 3636904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * preference hierarchy. 3646904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 3656904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param preferencesResId The XML resource ID to inflate. 3666904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 3676904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void addPreferencesFromResource(@XmlRes int preferencesResId) { 3686904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler requirePreferenceManager(); 3696904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3706904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler setPreferenceScreen(mPreferenceManager.inflateFromResource(mStyledContext, 3716904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler preferencesResId, getPreferenceScreen())); 3726904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3736904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3746904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 3756904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Inflates the given XML resource and replaces the current preference hierarchy (if any) with 3766904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * the preference hierarchy rooted at {@code key}. 3776904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 3786904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param preferencesResId The XML resource ID to inflate. 3796904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param key The preference key of the {@link android.support.v7.preference.PreferenceScreen} 3806904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * to use as the root of the preference hierarchy, or null to use the root 3816904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link android.support.v7.preference.PreferenceScreen}. 3826904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 3836904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void setPreferencesFromResource(@XmlRes int preferencesResId, @Nullable String key) { 3846904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler requirePreferenceManager(); 3856904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3866904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final PreferenceScreen xmlRoot = mPreferenceManager.inflateFromResource(mStyledContext, 3876904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler preferencesResId, null); 3886904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 3896904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final Preference root; 3906904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (key != null) { 3916904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler root = xmlRoot.findPreference(key); 3926904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (!(root instanceof PreferenceScreen)) { 3936904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler throw new IllegalArgumentException("Preference object with key " + key 3946904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler + " is not a PreferenceScreen"); 3956904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3966904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } else { 3976904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler root = xmlRoot; 3986904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 3996904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4006904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler setPreferenceScreen((PreferenceScreen) root); 4016904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4026904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4036904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 4046904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@inheritDoc} 4056904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 4066904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public boolean onPreferenceTreeClick(Preference preference) { 407c4868c8a2946a038466f51875a590759092137b2Tony Mantler if (preference.getFragment() != null) { 408c4868c8a2946a038466f51875a590759092137b2Tony Mantler boolean handled = false; 40941e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler if (getCallbackFragment() instanceof OnPreferenceStartFragmentCallback) { 41041e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler handled = ((OnPreferenceStartFragmentCallback) getCallbackFragment()) 411c4868c8a2946a038466f51875a590759092137b2Tony Mantler .onPreferenceStartFragment(this, preference); 412c4868c8a2946a038466f51875a590759092137b2Tony Mantler } 413c4868c8a2946a038466f51875a590759092137b2Tony Mantler if (!handled && getActivity() instanceof OnPreferenceStartFragmentCallback){ 414c4868c8a2946a038466f51875a590759092137b2Tony Mantler handled = ((OnPreferenceStartFragmentCallback) getActivity()) 415c4868c8a2946a038466f51875a590759092137b2Tony Mantler .onPreferenceStartFragment(this, preference); 416c4868c8a2946a038466f51875a590759092137b2Tony Mantler } 417c4868c8a2946a038466f51875a590759092137b2Tony Mantler return handled; 4186904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4196904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler return false; 4206904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4216904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4226904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 4236904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Called by 4246904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link android.support.v7.preference.PreferenceScreen#onClick()} in order to navigate to a 4256904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * new screen of preferences. Calls 4266904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link PreferenceFragment.OnPreferenceStartScreenCallback#onPreferenceStartScreen} 427c4868c8a2946a038466f51875a590759092137b2Tony Mantler * if the target fragment or containing activity implements 4286904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link PreferenceFragment.OnPreferenceStartScreenCallback}. 4296904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param preferenceScreen The {@link android.support.v7.preference.PreferenceScreen} to 4306904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * navigate to. 4316904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 4326904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler @Override 4336904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void onNavigateToScreen(PreferenceScreen preferenceScreen) { 434bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler boolean handled = false; 43541e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler if (getCallbackFragment() instanceof OnPreferenceStartScreenCallback) { 43641e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler handled = ((OnPreferenceStartScreenCallback) getCallbackFragment()) 437bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler .onPreferenceStartScreen(this, preferenceScreen); 438bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler } 439bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler if (!handled && getActivity() instanceof OnPreferenceStartScreenCallback) { 440bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler ((OnPreferenceStartScreenCallback) getActivity()) 441bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler .onPreferenceStartScreen(this, preferenceScreen); 4426904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4436904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4446904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4456904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 4466904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Finds a {@link Preference} based on its key. 4476904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 4486904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param key The key of the preference to retrieve. 4496904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @return The {@link Preference} with the key, or null. 4506904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @see android.support.v7.preference.PreferenceGroup#findPreference(CharSequence) 4516904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 4526904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public Preference findPreference(CharSequence key) { 4536904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (mPreferenceManager == null) { 4546904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler return null; 4556904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4566904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler return mPreferenceManager.findPreference(key); 4576904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4586904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4596904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private void requirePreferenceManager() { 4606904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (mPreferenceManager == null) { 4616904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler throw new RuntimeException("This should be called after super.onCreate."); 4626904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4636904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4646904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4656904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private void postBindPreferences() { 4666904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) return; 4676904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget(); 4686904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4696904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4706904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler private void bindPreferences() { 4716904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final PreferenceScreen preferenceScreen = getPreferenceScreen(); 4726904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (preferenceScreen != null) { 47353b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler getListView().setAdapter(onCreateAdapter(preferenceScreen)); 474e61b4475e1837034d8926593aff9d35f8dfaebe2Tony Mantler preferenceScreen.onAttached(); 4756904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4766904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler onBindPreferences(); 4776904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4786904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4796904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** @hide */ 4806904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler protected void onBindPreferences() { 4816904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4826904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4836904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** @hide */ 4846904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler protected void onUnbindPreferences() { 4856904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4866904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4876904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public final RecyclerView getListView() { 4886904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler return mList; 4896904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 4906904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 4916904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 4926904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Creates the {@link android.support.v7.widget.RecyclerView} used to display the preferences. 4936904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Subclasses may override this to return a customized 4946904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link android.support.v7.widget.RecyclerView}. 4956904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param inflater The LayoutInflater object that can be used to inflate the 4966904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link android.support.v7.widget.RecyclerView}. 4976904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param parent The parent {@link android.view.View} that the RecyclerView will be attached to. 4986904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * This method should not add the view itself, but this can be used to generate 4996904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * the LayoutParams of the view. 5006904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param savedInstanceState If non-null, this view is being re-constructed from a previous 5016904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * saved state as given here 5026904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @return A new RecyclerView object to be placed into the view hierarchy 5036904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 5046904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent, 5056904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler Bundle savedInstanceState) { 5066904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler RecyclerView recyclerView = (RecyclerView) inflater 5076904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler .inflate(R.layout.preference_recyclerview, parent, false); 5086904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 5096904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler recyclerView.setLayoutManager(onCreateLayoutManager()); 5106904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 5116904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler return recyclerView; 5126904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 5136904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 5146904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 5156904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Called from {@link #onCreateRecyclerView} to create the 5166904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link android.support.v7.widget.RecyclerView.LayoutManager} for the created 5176904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link android.support.v7.widget.RecyclerView}. 5186904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @return A new {@link android.support.v7.widget.RecyclerView.LayoutManager} instance. 5196904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 5206904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public RecyclerView.LayoutManager onCreateLayoutManager() { 5216904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler return new LinearLayoutManager(getActivity()); 5226904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 5236904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 5246904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler /** 52553b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler * Creates the root adapter. 52653b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler * 52753b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler * @param preferenceScreen Preference screen object to create the adapter for. 52853b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler * @return An adapter that contains the preferences contained in this {@link PreferenceScreen}. 52953b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler */ 53053b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) { 53153b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler return new PreferenceGroupAdapter(preferenceScreen); 53253b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler } 53353b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler 53453b6dca0375b0b40d968f9e9d3dabda3e958fc41Tony Mantler /** 5356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Called when a preference in the tree requests to display a dialog. Subclasses should 5366904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * override this method to display custom dialogs or to handle dialogs for custom preference 5376904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * classes. 5386904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * 5396904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @param preference The Preference object requesting the dialog. 5406904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */ 5416904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler @Override 5426904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler public void onDisplayPreferenceDialog(Preference preference) { 543bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler 544bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler boolean handled = false; 54541e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler if (getCallbackFragment() instanceof OnPreferenceDisplayDialogCallback) { 54641e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler handled = ((OnPreferenceDisplayDialogCallback) getCallbackFragment()) 547bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler .onPreferenceDisplayDialog(this, preference); 548bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler } 549bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler if (!handled && getActivity() instanceof OnPreferenceDisplayDialogCallback) { 550bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler handled = ((OnPreferenceDisplayDialogCallback) getActivity()) 551bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler .onPreferenceDisplayDialog(this, preference); 552bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler } 553bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler 554bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler if (handled) { 555bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler return; 556bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler } 557bd4cbab53c68c95f62407cf872b7155a520748a0Tony Mantler 5586904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler // check if dialog is already showing 5596904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (getFragmentManager().findFragmentByTag(DIALOG_FRAGMENT_TAG) != null) { 5606904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler return; 5616904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 5626904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 5636904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler final DialogFragment f; 5646904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler if (preference instanceof EditTextPreference) { 5656904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler f = EditTextPreferenceDialogFragment.newInstance(preference.getKey()); 5666904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } else if (preference instanceof ListPreference) { 5676904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler f = ListPreferenceDialogFragment.newInstance(preference.getKey()); 5680112bacf4aa212f4d0da45594a88694f295ae56cTony Mantler } else if (preference instanceof MultiSelectListPreference) { 5690112bacf4aa212f4d0da45594a88694f295ae56cTony Mantler f = MultiSelectListPreferenceDialogFragment.newInstance(preference.getKey()); 5706904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } else { 5716904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler throw new IllegalArgumentException("Tried to display dialog for unknown " + 5726904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler "preference type. Did you forget to override onDisplayPreferenceDialog()?"); 5736904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 5746904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler f.setTargetFragment(this, 0); 5756904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler f.show(getFragmentManager(), DIALOG_FRAGMENT_TAG); 5766904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler } 5776904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler 57841e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler /** 57941e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler * Basically a wrapper for getParentFragment which is v17+. Used by the leanback preference lib. 58041e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler * @return Fragment to possibly use as a callback 58141e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler * @hide 58241e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler */ 58341e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler public Fragment getCallbackFragment() { 58441e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler return null; 58541e6b178ef361cdadcf27b8074e71b624df8fe3fTony Mantler } 5866904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler} 587