PreferenceFragment.java revision c56fc753e2e2d35221a1a4df353a435098268ec4
142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn/*
242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * Copyright (C) 2010 The Android Open Source Project
342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn *
442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * you may not use this file except in compliance with the License.
642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * You may obtain a copy of the License at
742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn *
842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn *
1042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * Unless required by applicable law or agreed to in writing, software
1142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
1242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * See the License for the specific language governing permissions and
1442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * limitations under the License.
1542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn */
1642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
1742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornpackage android.preference;
1842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
1942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.app.Activity;
2042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.app.Fragment;
2142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.content.Intent;
2242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.content.SharedPreferences;
2342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.os.Bundle;
2442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.os.Handler;
2542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.os.Message;
2642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.view.LayoutInflater;
2742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.view.View;
2842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.view.ViewGroup;
2942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.widget.ListView;
3042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
3142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn/**
3242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * Shows a hierarchy of {@link Preference} objects as
3342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * lists. These preferences will
3442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * automatically save to {@link SharedPreferences} as the user interacts with
3542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * them. To retrieve an instance of {@link SharedPreferences} that the
3642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * preference hierarchy in this fragment will use, call
3742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * {@link PreferenceManager#getDefaultSharedPreferences(android.content.Context)}
3842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * with a context in the same package as this fragment.
3942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <p>
40b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * Furthermore, the preferences shown will follow the visual style of system
41b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * preferences. It is easy to create a hierarchy of preferences (that can be
42b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * shown on multiple screens) via XML. For these reasons, it is recommended to
43b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * use this fragment (as a superclass) to deal with preferences in applications.
44b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <p>
45b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * A {@link PreferenceScreen} object should be at the top of the preference
46b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * hierarchy. Furthermore, subsequent {@link PreferenceScreen} in the hierarchy
47b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * denote a screen break--that is the preferences contained within subsequent
48b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * {@link PreferenceScreen} should be shown on another screen. The preference
49b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * framework handles showing these other screens from the preference hierarchy.
50b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <p>
5142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * The preference hierarchy can be formed in multiple ways:
5242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <li> From an XML file specifying the hierarchy
5342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <li> From different {@link Activity Activities} that each specify its own
5442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * preferences in an XML file via {@link Activity} meta-data
5542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <li> From an object hierarchy rooted with {@link PreferenceScreen}
5642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <p>
5742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * To inflate from XML, use the {@link #addPreferencesFromResource(int)}. The
5842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * root element should be a {@link PreferenceScreen}. Subsequent elements can point
5942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * to actual {@link Preference} subclasses. As mentioned above, subsequent
6042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * {@link PreferenceScreen} in the hierarchy will result in the screen break.
6142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <p>
6242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * To specify an {@link Intent} to query {@link Activity Activities} that each
6342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * have preferences, use {@link #addPreferencesFromIntent}. Each
6442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * {@link Activity} can specify meta-data in the manifest (via the key
6542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * {@link PreferenceManager#METADATA_KEY_PREFERENCES}) that points to an XML
6642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * resource. These XML resources will be inflated into a single preference
6742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * hierarchy and shown by this fragment.
6842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <p>
6942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * To specify an object hierarchy rooted with {@link PreferenceScreen}, use
7042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * {@link #setPreferenceScreen(PreferenceScreen)}.
7142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <p>
7242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * As a convenience, this fragment implements a click listener for any
7342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * preference in the current hierarchy, see
7442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * {@link #onPreferenceTreeClick(PreferenceScreen, Preference)}.
7542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn *
7642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <a name="SampleCode"></a>
7742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <h3>Sample Code</h3>
7842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn *
79b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <p>The following sample code shows a simple preference fragment that is
80b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * populated from a resource.  The resource it loads is:</p>
8142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn *
82b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * {@sample development/samples/ApiDemos/res/xml/preferences.xml preferences}
8342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn *
84b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <p>The fragment implementation itself simply populates the preferences
85b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * when created.  Note that the preferences framework takes care of loading
86b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * the current values out of the app preferences and writing them when changed:</p>
8742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn *
88b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * {@sample development/samples/ApiDemos/src/com/example/android/apis/preference/FragmentPreferences.java
89b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn *      fragment}
9042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn *
9142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * @see Preference
9242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * @see PreferenceScreen
9342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn */
9442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornpublic abstract class PreferenceFragment extends Fragment implements
9542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        PreferenceManager.OnPreferenceTreeClickListener {
9642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
9742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private static final String PREFERENCES_TAG = "android:preferences";
9842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
9942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private PreferenceManager mPreferenceManager;
10042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private ListView mList;
10142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private boolean mHavePrefs;
10242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private boolean mInitDone;
10342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
10442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    /**
10542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * The starting request code given out to preference framework.
10642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     */
10742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private static final int FIRST_REQUEST_CODE = 100;
10842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
1093e449ce00ed2d3b271e50bc7a52798f630973bf1Dianne Hackborn    private static final int MSG_BIND_PREFERENCES = 1;
11042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private Handler mHandler = new Handler() {
11142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        @Override
11242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        public void handleMessage(Message msg) {
11342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            switch (msg.what) {
11442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
11542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                case MSG_BIND_PREFERENCES:
11642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                    bindPreferences();
11742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                    break;
11842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            }
11942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
12042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    };
12142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
12242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    final private Runnable mRequestFocus = new Runnable() {
12342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        public void run() {
12442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            mList.focusableViewAvailable(mList);
12542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
12642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    };
12742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
128b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn    /**
129b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn     * Interface that PreferenceFragment's containing activity should
130b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn     * implement to be able to process preference items that wish to
131b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn     * switch to a new fragment.
132b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn     */
133b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn    public interface OnPreferenceStartFragmentCallback {
134b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn        /**
135b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn         * Called when the user has clicked on a Preference that has
136b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn         * a fragment class name associated with it.  The implementation
137b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn         * to should instantiate and switch to an instance of the given
138b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn         * fragment.
139b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn         */
140b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn        boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref);
141b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn    }
142b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn
14342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    @Override
14442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public void onCreate(Bundle savedInstanceState) {
14542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        super.onCreate(savedInstanceState);
14642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        mPreferenceManager = new PreferenceManager(getActivity(), FIRST_REQUEST_CODE);
14782e7bc11342547d1480ef89208ed06943650e201Amith Yamasani        mPreferenceManager.setFragment(this);
14842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
14942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
15042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    @Override
15142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public View onCreateView(LayoutInflater inflater, ViewGroup container,
15242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            Bundle savedInstanceState) {
15327da0bf0a38231111cbf6bb7df6c4a0d53b144d8Amith Yamasani        return inflater.inflate(com.android.internal.R.layout.preference_list_fragment,
15442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                container, false);
15542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
15642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
15742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    @Override
15842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public void onActivityCreated(Bundle savedInstanceState) {
15942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        super.onActivityCreated(savedInstanceState);
16042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        getListView().setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
16142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
16242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (mHavePrefs) {
16342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            bindPreferences();
16442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
16542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
16642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        mInitDone = true;
16742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
16842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (savedInstanceState != null) {
16942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            Bundle container = savedInstanceState.getBundle(PREFERENCES_TAG);
17042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            if (container != null) {
17142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                final PreferenceScreen preferenceScreen = getPreferenceScreen();
17242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                if (preferenceScreen != null) {
17342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                    preferenceScreen.restoreHierarchyState(container);
17442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                }
17542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            }
17642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
17742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
17842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
17942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    @Override
180c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani    public void onStart() {
181c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani        super.onStart();
182c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani        mPreferenceManager.setOnPreferenceTreeClickListener(this);
183c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani    }
184c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani
185c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani    @Override
18642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public void onStop() {
18742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        super.onStop();
18842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        mPreferenceManager.dispatchActivityStop();
189c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani        mPreferenceManager.setOnPreferenceTreeClickListener(null);
19042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
19142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
19242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    @Override
193b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn    public void onDestroyView() {
194b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn        mList = null;
195b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn        mHandler.removeCallbacks(mRequestFocus);
19681d860013c7eeb96a09574301485d3e405ce03bcAmith Yamasani        mHandler.removeMessages(MSG_BIND_PREFERENCES);
197b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn        super.onDestroyView();
198b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn    }
199b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn
200b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn    @Override
20142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public void onDestroy() {
20242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        super.onDestroy();
20342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        mPreferenceManager.dispatchActivityDestroy();
20442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
20542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
20642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    @Override
20742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public void onSaveInstanceState(Bundle outState) {
20842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        super.onSaveInstanceState(outState);
20942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
21042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        final PreferenceScreen preferenceScreen = getPreferenceScreen();
21142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (preferenceScreen != null) {
21242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            Bundle container = new Bundle();
21342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            preferenceScreen.saveHierarchyState(container);
21442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            outState.putBundle(PREFERENCES_TAG, container);
21542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
21642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
21742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
21842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    @Override
21942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public void onActivityResult(int requestCode, int resultCode, Intent data) {
22042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        super.onActivityResult(requestCode, resultCode, data);
22142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
22242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        mPreferenceManager.dispatchActivityResult(requestCode, resultCode, data);
22342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
22442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
22542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    /**
22642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * Returns the {@link PreferenceManager} used by this fragment.
22742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * @return The {@link PreferenceManager}.
22842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     */
22942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public PreferenceManager getPreferenceManager() {
23042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        return mPreferenceManager;
23142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
23242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
23342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    /**
23442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * Sets the root of the preference hierarchy that this fragment is showing.
23542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     *
23642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy.
23742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     */
23842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
23942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (mPreferenceManager.setPreferences(preferenceScreen) && preferenceScreen != null) {
24042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            mHavePrefs = true;
24142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            if (mInitDone) {
24242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                postBindPreferences();
24342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            }
24442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
24542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
24642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
24742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    /**
24842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * Gets the root of the preference hierarchy that this fragment is showing.
24942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     *
25042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * @return The {@link PreferenceScreen} that is the root of the preference
25142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     *         hierarchy.
25242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     */
25342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public PreferenceScreen getPreferenceScreen() {
25442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        return mPreferenceManager.getPreferenceScreen();
25542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
25642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
25742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    /**
25842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * Adds preferences from activities that match the given {@link Intent}.
25942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     *
26042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * @param intent The {@link Intent} to query activities.
26142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     */
26242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public void addPreferencesFromIntent(Intent intent) {
26342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        requirePreferenceManager();
26442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
26542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        setPreferenceScreen(mPreferenceManager.inflateFromIntent(intent, getPreferenceScreen()));
26642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
26742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
26842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    /**
26942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * Inflates the given XML resource and adds the preference hierarchy to the current
27042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * preference hierarchy.
27142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     *
27242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * @param preferencesResId The XML resource ID to inflate.
27342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     */
27442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public void addPreferencesFromResource(int preferencesResId) {
27542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        requirePreferenceManager();
27642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
27742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        setPreferenceScreen(mPreferenceManager.inflateFromResource(getActivity(),
27842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                preferencesResId, getPreferenceScreen()));
27942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
28042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
28142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    /**
28242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * {@inheritDoc}
28342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     */
284b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
285b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn            Preference preference) {
286b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn        if (preference.getFragment() != null &&
287b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn                getActivity() instanceof OnPreferenceStartFragmentCallback) {
288b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn            return ((OnPreferenceStartFragmentCallback)getActivity()).onPreferenceStartFragment(
289b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn                    this, preference);
290b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn        }
29142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        return false;
29242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
29342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
29442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    /**
29542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * Finds a {@link Preference} based on its key.
29642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     *
29742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * @param key The key of the preference to retrieve.
29842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * @return The {@link Preference} with the key, or null.
29942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * @see PreferenceGroup#findPreference(CharSequence)
30042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     */
30142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public Preference findPreference(CharSequence key) {
30242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (mPreferenceManager == null) {
30342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            return null;
30442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
30542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        return mPreferenceManager.findPreference(key);
30642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
30742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
30842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private void requirePreferenceManager() {
30942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (mPreferenceManager == null) {
31042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            throw new RuntimeException("This should be called after super.onCreate.");
31142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
31242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
31342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
31442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private void postBindPreferences() {
31542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) return;
31642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget();
31742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
31842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
31942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private void bindPreferences() {
32042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        final PreferenceScreen preferenceScreen = getPreferenceScreen();
32142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (preferenceScreen != null) {
32242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            preferenceScreen.bind(getListView());
32342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
32442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
32542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
3269ae5473eae5312575521d87ec0303ac91560cbedAmith Yamasani    /** @hide */
3279ae5473eae5312575521d87ec0303ac91560cbedAmith Yamasani    public ListView getListView() {
32842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        ensureList();
32942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        return mList;
33042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
33142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
33242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private void ensureList() {
33342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (mList != null) {
33442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            return;
33542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
33642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        View root = getView();
33742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (root == null) {
33842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            throw new IllegalStateException("Content view not yet created");
33942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
34042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        View rawListView = root.findViewById(android.R.id.list);
34142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (!(rawListView instanceof ListView)) {
34242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            throw new RuntimeException(
34342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                    "Content has view with id attribute 'android.R.id.list' "
34442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                    + "that is not a ListView class");
34542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
34642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        mList = (ListView)rawListView;
34742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (mList == null) {
34842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            throw new RuntimeException(
34942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                    "Your content must have a ListView whose id attribute is " +
35042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                    "'android.R.id.list'");
35142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
35242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        mHandler.post(mRequestFocus);
35342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
35442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn}
355