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
193c32b620448673dd47f869e2029e12b72ee21ed1Scott Kennedyimport android.annotation.Nullable;
20417ee5ba89f7e0fe5efd34fce74bf1ee5923d976Tor Norbyeimport android.annotation.XmlRes;
2142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.app.Activity;
2242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.app.Fragment;
2342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.content.Intent;
2442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.content.SharedPreferences;
25f9499b36e689dee5cec2cb7bb0b7d21f7c302d84Fabrice Di Meglioimport android.content.res.TypedArray;
267fc97c913487c4df97b8af111390942d61c1d331Jason Monkimport android.graphics.drawable.Drawable;
2742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.os.Bundle;
2842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.os.Handler;
2942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.os.Message;
30744be16ffa030cb62de13f633c124fc0e72d0181Michael Kwanimport android.text.TextUtils;
31014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reckimport android.view.KeyEvent;
3242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.view.LayoutInflater;
3342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.view.View;
34014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reckimport android.view.View.OnKeyListener;
357fc97c913487c4df97b8af111390942d61c1d331Jason Monkimport android.view.ViewGroup;
3642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornimport android.widget.ListView;
37744be16ffa030cb62de13f633c124fc0e72d0181Michael Kwanimport android.widget.TextView;
3842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
3942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn/**
4042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * Shows a hierarchy of {@link Preference} objects as
4142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * lists. These preferences will
4242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * automatically save to {@link SharedPreferences} as the user interacts with
4342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * them. To retrieve an instance of {@link SharedPreferences} that the
4442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * preference hierarchy in this fragment will use, call
4542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * {@link PreferenceManager#getDefaultSharedPreferences(android.content.Context)}
4642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * with a context in the same package as this fragment.
4742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <p>
48b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * Furthermore, the preferences shown will follow the visual style of system
49b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * preferences. It is easy to create a hierarchy of preferences (that can be
50b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * shown on multiple screens) via XML. For these reasons, it is recommended to
51b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * use this fragment (as a superclass) to deal with preferences in applications.
52b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <p>
53b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * A {@link PreferenceScreen} object should be at the top of the preference
54b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * hierarchy. Furthermore, subsequent {@link PreferenceScreen} in the hierarchy
55b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * denote a screen break--that is the preferences contained within subsequent
56b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * {@link PreferenceScreen} should be shown on another screen. The preference
57b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * framework handles showing these other screens from the preference hierarchy.
58b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <p>
5942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * The preference hierarchy can be formed in multiple ways:
6042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <li> From an XML file specifying the hierarchy
6142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <li> From different {@link Activity Activities} that each specify its own
6242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * preferences in an XML file via {@link Activity} meta-data
6342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <li> From an object hierarchy rooted with {@link PreferenceScreen}
6442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <p>
6542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * To inflate from XML, use the {@link #addPreferencesFromResource(int)}. The
6642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * root element should be a {@link PreferenceScreen}. Subsequent elements can point
6742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * to actual {@link Preference} subclasses. As mentioned above, subsequent
6842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * {@link PreferenceScreen} in the hierarchy will result in the screen break.
6942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <p>
7042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * To specify an {@link Intent} to query {@link Activity Activities} that each
7142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * have preferences, use {@link #addPreferencesFromIntent}. Each
7242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * {@link Activity} can specify meta-data in the manifest (via the key
7342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * {@link PreferenceManager#METADATA_KEY_PREFERENCES}) that points to an XML
7442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * resource. These XML resources will be inflated into a single preference
7542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * hierarchy and shown by this fragment.
7642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <p>
7742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * To specify an object hierarchy rooted with {@link PreferenceScreen}, use
7842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * {@link #setPreferenceScreen(PreferenceScreen)}.
7942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <p>
8042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * As a convenience, this fragment implements a click listener for any
8142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * preference in the current hierarchy, see
8242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * {@link #onPreferenceTreeClick(PreferenceScreen, Preference)}.
83cdd0c59a0108036895796dcb2bea69ff5eef26caScott Main *
84cdd0c59a0108036895796dcb2bea69ff5eef26caScott Main * <div class="special reference">
85cdd0c59a0108036895796dcb2bea69ff5eef26caScott Main * <h3>Developer Guides</h3>
86cdd0c59a0108036895796dcb2bea69ff5eef26caScott Main * <p>For information about using {@code PreferenceFragment},
87cdd0c59a0108036895796dcb2bea69ff5eef26caScott Main * read the <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a>
88cdd0c59a0108036895796dcb2bea69ff5eef26caScott Main * guide.</p>
89cdd0c59a0108036895796dcb2bea69ff5eef26caScott Main * </div>
9042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn *
9142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <a name="SampleCode"></a>
9242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * <h3>Sample Code</h3>
9342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn *
94b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <p>The following sample code shows a simple preference fragment that is
95b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * populated from a resource.  The resource it loads is:</p>
9642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn *
97b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * {@sample development/samples/ApiDemos/res/xml/preferences.xml preferences}
9842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn *
99b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * <p>The fragment implementation itself simply populates the preferences
100b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * when created.  Note that the preferences framework takes care of loading
101b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * the current values out of the app preferences and writing them when changed:</p>
10242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn *
103b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn * {@sample development/samples/ApiDemos/src/com/example/android/apis/preference/FragmentPreferences.java
104b1ad5977bc8178b6d350ebe9099daded4c1ef603Dianne Hackborn *      fragment}
10542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn *
10642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * @see Preference
10742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn * @see PreferenceScreen
10842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn */
10942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackbornpublic abstract class PreferenceFragment extends Fragment implements
11042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        PreferenceManager.OnPreferenceTreeClickListener {
11142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
11242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private static final String PREFERENCES_TAG = "android:preferences";
11342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
11442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private PreferenceManager mPreferenceManager;
11542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private ListView mList;
11642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private boolean mHavePrefs;
11742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private boolean mInitDone;
11842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
119f9499b36e689dee5cec2cb7bb0b7d21f7c302d84Fabrice Di Meglio    private int mLayoutResId = com.android.internal.R.layout.preference_list_fragment;
120f9499b36e689dee5cec2cb7bb0b7d21f7c302d84Fabrice Di Meglio
12142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    /**
12242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * The starting request code given out to preference framework.
12342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     */
12442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private static final int FIRST_REQUEST_CODE = 100;
12542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
1263e449ce00ed2d3b271e50bc7a52798f630973bf1Dianne Hackborn    private static final int MSG_BIND_PREFERENCES = 1;
12742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private Handler mHandler = new Handler() {
12842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        @Override
12942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        public void handleMessage(Message msg) {
13042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            switch (msg.what) {
13142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
13242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                case MSG_BIND_PREFERENCES:
13342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                    bindPreferences();
13442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                    break;
13542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            }
13642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
13742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    };
13842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
13942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    final private Runnable mRequestFocus = new Runnable() {
14042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        public void run() {
14142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            mList.focusableViewAvailable(mList);
14242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
14342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    };
14442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
145b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn    /**
146b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn     * Interface that PreferenceFragment's containing activity should
147b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn     * implement to be able to process preference items that wish to
148b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn     * switch to a new fragment.
149b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn     */
150b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn    public interface OnPreferenceStartFragmentCallback {
151b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn        /**
152b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn         * Called when the user has clicked on a Preference that has
153b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn         * a fragment class name associated with it.  The implementation
154b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn         * to should instantiate and switch to an instance of the given
155b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn         * fragment.
156b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn         */
157b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn        boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref);
158b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn    }
159b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn
16042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    @Override
1613c32b620448673dd47f869e2029e12b72ee21ed1Scott Kennedy    public void onCreate(@Nullable Bundle savedInstanceState) {
16242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        super.onCreate(savedInstanceState);
16342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        mPreferenceManager = new PreferenceManager(getActivity(), FIRST_REQUEST_CODE);
16482e7bc11342547d1480ef89208ed06943650e201Amith Yamasani        mPreferenceManager.setFragment(this);
16542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
16642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
16742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    @Override
1683c32b620448673dd47f869e2029e12b72ee21ed1Scott Kennedy    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
1693c32b620448673dd47f869e2029e12b72ee21ed1Scott Kennedy            @Nullable Bundle savedInstanceState) {
170f9499b36e689dee5cec2cb7bb0b7d21f7c302d84Fabrice Di Meglio
171f9499b36e689dee5cec2cb7bb0b7d21f7c302d84Fabrice Di Meglio        TypedArray a = getActivity().obtainStyledAttributes(null,
172f9499b36e689dee5cec2cb7bb0b7d21f7c302d84Fabrice Di Meglio                com.android.internal.R.styleable.PreferenceFragment,
173f9499b36e689dee5cec2cb7bb0b7d21f7c302d84Fabrice Di Meglio                com.android.internal.R.attr.preferenceFragmentStyle,
174f9499b36e689dee5cec2cb7bb0b7d21f7c302d84Fabrice Di Meglio                0);
175f9499b36e689dee5cec2cb7bb0b7d21f7c302d84Fabrice Di Meglio
176f9499b36e689dee5cec2cb7bb0b7d21f7c302d84Fabrice Di Meglio        mLayoutResId = a.getResourceId(com.android.internal.R.styleable.PreferenceFragment_layout,
177f9499b36e689dee5cec2cb7bb0b7d21f7c302d84Fabrice Di Meglio                mLayoutResId);
178f9499b36e689dee5cec2cb7bb0b7d21f7c302d84Fabrice Di Meglio
179f9499b36e689dee5cec2cb7bb0b7d21f7c302d84Fabrice Di Meglio        a.recycle();
180f9499b36e689dee5cec2cb7bb0b7d21f7c302d84Fabrice Di Meglio
181f9499b36e689dee5cec2cb7bb0b7d21f7c302d84Fabrice Di Meglio        return inflater.inflate(mLayoutResId, container, false);
18242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
18342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
18442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    @Override
1857fc97c913487c4df97b8af111390942d61c1d331Jason Monk    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
1867fc97c913487c4df97b8af111390942d61c1d331Jason Monk        super.onViewCreated(view, savedInstanceState);
1877fc97c913487c4df97b8af111390942d61c1d331Jason Monk
1887fc97c913487c4df97b8af111390942d61c1d331Jason Monk        TypedArray a = getActivity().obtainStyledAttributes(null,
1897fc97c913487c4df97b8af111390942d61c1d331Jason Monk                com.android.internal.R.styleable.PreferenceFragment,
1907fc97c913487c4df97b8af111390942d61c1d331Jason Monk                com.android.internal.R.attr.preferenceFragmentStyle,
1917fc97c913487c4df97b8af111390942d61c1d331Jason Monk                0);
1927fc97c913487c4df97b8af111390942d61c1d331Jason Monk
1937fc97c913487c4df97b8af111390942d61c1d331Jason Monk        ListView lv = (ListView) view.findViewById(android.R.id.list);
194908523014e8cdc04c65c85a95be0c8ca98113c06Michael Kwan        if (lv != null
195908523014e8cdc04c65c85a95be0c8ca98113c06Michael Kwan                && a.hasValueOrEmpty(com.android.internal.R.styleable.PreferenceFragment_divider)) {
196908523014e8cdc04c65c85a95be0c8ca98113c06Michael Kwan            lv.setDivider(
197908523014e8cdc04c65c85a95be0c8ca98113c06Michael Kwan                    a.getDrawable(com.android.internal.R.styleable.PreferenceFragment_divider));
1987fc97c913487c4df97b8af111390942d61c1d331Jason Monk        }
1997fc97c913487c4df97b8af111390942d61c1d331Jason Monk
2007fc97c913487c4df97b8af111390942d61c1d331Jason Monk        a.recycle();
2017fc97c913487c4df97b8af111390942d61c1d331Jason Monk    }
2027fc97c913487c4df97b8af111390942d61c1d331Jason Monk
2037fc97c913487c4df97b8af111390942d61c1d331Jason Monk    @Override
2043c32b620448673dd47f869e2029e12b72ee21ed1Scott Kennedy    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
20542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        super.onActivityCreated(savedInstanceState);
20642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
20742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (mHavePrefs) {
20842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            bindPreferences();
20942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
21042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
21142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        mInitDone = true;
21242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
21342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (savedInstanceState != null) {
21442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            Bundle container = savedInstanceState.getBundle(PREFERENCES_TAG);
21542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            if (container != null) {
21642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                final PreferenceScreen preferenceScreen = getPreferenceScreen();
21742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                if (preferenceScreen != null) {
21842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                    preferenceScreen.restoreHierarchyState(container);
21942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                }
22042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            }
22142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
22242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
22342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
22442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    @Override
225c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani    public void onStart() {
226c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani        super.onStart();
227c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani        mPreferenceManager.setOnPreferenceTreeClickListener(this);
228c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani    }
229c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani
230c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani    @Override
23142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public void onStop() {
23242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        super.onStop();
23342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        mPreferenceManager.dispatchActivityStop();
234c56fc753e2e2d35221a1a4df353a435098268ec4Amith Yamasani        mPreferenceManager.setOnPreferenceTreeClickListener(null);
23542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
23642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
23742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    @Override
238b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn    public void onDestroyView() {
2395e18c40d28cba98607d34f50e972c4d977c3dd6cMykola Kondratenko        if (mList != null) {
2405e18c40d28cba98607d34f50e972c4d977c3dd6cMykola Kondratenko            mList.setOnKeyListener(null);
2415e18c40d28cba98607d34f50e972c4d977c3dd6cMykola Kondratenko        }
242b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn        mList = null;
243b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn        mHandler.removeCallbacks(mRequestFocus);
24481d860013c7eeb96a09574301485d3e405ce03bcAmith Yamasani        mHandler.removeMessages(MSG_BIND_PREFERENCES);
245b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn        super.onDestroyView();
246b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn    }
247b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn
248b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn    @Override
24942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public void onDestroy() {
25042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        super.onDestroy();
25142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        mPreferenceManager.dispatchActivityDestroy();
25242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
25342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
25442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    @Override
25542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public void onSaveInstanceState(Bundle outState) {
25642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        super.onSaveInstanceState(outState);
25742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
25842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        final PreferenceScreen preferenceScreen = getPreferenceScreen();
25942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (preferenceScreen != null) {
26042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            Bundle container = new Bundle();
26142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            preferenceScreen.saveHierarchyState(container);
26242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            outState.putBundle(PREFERENCES_TAG, container);
26342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
26442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
26542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
26642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    @Override
26742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public void onActivityResult(int requestCode, int resultCode, Intent data) {
26842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        super.onActivityResult(requestCode, resultCode, data);
26942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
27042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        mPreferenceManager.dispatchActivityResult(requestCode, resultCode, data);
27142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
27242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
27342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    /**
27442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * Returns the {@link PreferenceManager} used by this fragment.
27542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * @return The {@link PreferenceManager}.
27642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     */
27742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public PreferenceManager getPreferenceManager() {
27842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        return mPreferenceManager;
27942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
28042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
28142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    /**
28242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * Sets the root of the preference hierarchy that this fragment is showing.
28342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     *
28442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy.
28542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     */
28642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
28742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (mPreferenceManager.setPreferences(preferenceScreen) && preferenceScreen != null) {
288b1a50f2dff3d2d24c3567e2be67e7a4bc87a9b31Fabrice Di Meglio            onUnbindPreferences();
28942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            mHavePrefs = true;
29042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            if (mInitDone) {
29142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                postBindPreferences();
29242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            }
29342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
29442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
29542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
29642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    /**
29742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * Gets the root of the preference hierarchy that this fragment is showing.
29842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     *
29942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * @return The {@link PreferenceScreen} that is the root of the preference
30042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     *         hierarchy.
30142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     */
30242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public PreferenceScreen getPreferenceScreen() {
30342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        return mPreferenceManager.getPreferenceScreen();
30442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
30542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
30642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    /**
30742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * Adds preferences from activities that match the given {@link Intent}.
30842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     *
30942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * @param intent The {@link Intent} to query activities.
31042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     */
31142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public void addPreferencesFromIntent(Intent intent) {
31242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        requirePreferenceManager();
31342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
31442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        setPreferenceScreen(mPreferenceManager.inflateFromIntent(intent, getPreferenceScreen()));
31542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
31642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
31742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    /**
31842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * Inflates the given XML resource and adds the preference hierarchy to the current
31942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * preference hierarchy.
32042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     *
32142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * @param preferencesResId The XML resource ID to inflate.
32242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     */
323417ee5ba89f7e0fe5efd34fce74bf1ee5923d976Tor Norbye    public void addPreferencesFromResource(@XmlRes int preferencesResId) {
32442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        requirePreferenceManager();
32542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
32642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        setPreferenceScreen(mPreferenceManager.inflateFromResource(getActivity(),
32742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                preferencesResId, getPreferenceScreen()));
32842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
32942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
33042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    /**
33142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * {@inheritDoc}
33242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     */
333b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
334b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn            Preference preference) {
335b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn        if (preference.getFragment() != null &&
336b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn                getActivity() instanceof OnPreferenceStartFragmentCallback) {
337b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn            return ((OnPreferenceStartFragmentCallback)getActivity()).onPreferenceStartFragment(
338b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn                    this, preference);
339b3cf10ffa8ff9cac0da8b23a0d84076b3f501400Dianne Hackborn        }
34042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        return false;
34142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
34242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
34342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    /**
34442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * Finds a {@link Preference} based on its key.
34542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     *
34642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * @param key The key of the preference to retrieve.
34742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * @return The {@link Preference} with the key, or null.
34842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     * @see PreferenceGroup#findPreference(CharSequence)
34942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn     */
35042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    public Preference findPreference(CharSequence key) {
35142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (mPreferenceManager == null) {
35242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            return null;
35342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
35442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        return mPreferenceManager.findPreference(key);
35542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
35642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
35742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private void requirePreferenceManager() {
35842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (mPreferenceManager == null) {
35942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            throw new RuntimeException("This should be called after super.onCreate.");
36042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
36142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
36242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
36342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private void postBindPreferences() {
36442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) return;
36542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget();
36642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
36742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
36842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private void bindPreferences() {
36942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        final PreferenceScreen preferenceScreen = getPreferenceScreen();
37042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (preferenceScreen != null) {
371744be16ffa030cb62de13f633c124fc0e72d0181Michael Kwan            View root = getView();
372744be16ffa030cb62de13f633c124fc0e72d0181Michael Kwan            if (root != null) {
373744be16ffa030cb62de13f633c124fc0e72d0181Michael Kwan                View titleView = root.findViewById(android.R.id.title);
374744be16ffa030cb62de13f633c124fc0e72d0181Michael Kwan                if (titleView instanceof TextView) {
375744be16ffa030cb62de13f633c124fc0e72d0181Michael Kwan                    CharSequence title = preferenceScreen.getTitle();
376744be16ffa030cb62de13f633c124fc0e72d0181Michael Kwan                    if (TextUtils.isEmpty(title)) {
377744be16ffa030cb62de13f633c124fc0e72d0181Michael Kwan                        titleView.setVisibility(View.GONE);
378744be16ffa030cb62de13f633c124fc0e72d0181Michael Kwan                    } else {
379744be16ffa030cb62de13f633c124fc0e72d0181Michael Kwan                        ((TextView) titleView).setText(title);
380744be16ffa030cb62de13f633c124fc0e72d0181Michael Kwan                        titleView.setVisibility(View.VISIBLE);
381744be16ffa030cb62de13f633c124fc0e72d0181Michael Kwan                    }
382744be16ffa030cb62de13f633c124fc0e72d0181Michael Kwan                }
383744be16ffa030cb62de13f633c124fc0e72d0181Michael Kwan            }
384744be16ffa030cb62de13f633c124fc0e72d0181Michael Kwan
38542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            preferenceScreen.bind(getListView());
38642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
3878a86d734e53dcbafd86c5cc28679323798ecd8a5Fabrice Di Meglio        onBindPreferences();
3888a86d734e53dcbafd86c5cc28679323798ecd8a5Fabrice Di Meglio    }
3898a86d734e53dcbafd86c5cc28679323798ecd8a5Fabrice Di Meglio
3908a86d734e53dcbafd86c5cc28679323798ecd8a5Fabrice Di Meglio    /** @hide */
3918a86d734e53dcbafd86c5cc28679323798ecd8a5Fabrice Di Meglio    protected void onBindPreferences() {
39242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
39342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
3949ae5473eae5312575521d87ec0303ac91560cbedAmith Yamasani    /** @hide */
395b1a50f2dff3d2d24c3567e2be67e7a4bc87a9b31Fabrice Di Meglio    protected void onUnbindPreferences() {
396b1a50f2dff3d2d24c3567e2be67e7a4bc87a9b31Fabrice Di Meglio    }
397b1a50f2dff3d2d24c3567e2be67e7a4bc87a9b31Fabrice Di Meglio
398b1a50f2dff3d2d24c3567e2be67e7a4bc87a9b31Fabrice Di Meglio    /** @hide */
3999ae5473eae5312575521d87ec0303ac91560cbedAmith Yamasani    public ListView getListView() {
40042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        ensureList();
40142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        return mList;
40242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
40342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn
40435d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio    /** @hide */
40535d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio    public boolean hasListView() {
40635d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio        if (mList != null) {
40735d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio            return true;
40835d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio        }
40935d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio        View root = getView();
41035d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio        if (root == null) {
41135d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio            return false;
41235d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio        }
41335d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio        View rawListView = root.findViewById(android.R.id.list);
41435d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio        if (!(rawListView instanceof ListView)) {
41535d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio            return false;
41635d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio        }
41735d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio        mList = (ListView)rawListView;
41835d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio        if (mList == null) {
41935d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio            return false;
42035d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio        }
42135d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio        return true;
42235d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio    }
42335d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio
42442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    private void ensureList() {
42542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (mList != null) {
42642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            return;
42742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
42842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        View root = getView();
42942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (root == null) {
43042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            throw new IllegalStateException("Content view not yet created");
43142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
43242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        View rawListView = root.findViewById(android.R.id.list);
43342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (!(rawListView instanceof ListView)) {
43442c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            throw new RuntimeException(
43542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                    "Content has view with id attribute 'android.R.id.list' "
43642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                    + "that is not a ListView class");
43742c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
43842c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        mList = (ListView)rawListView;
43942c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        if (mList == null) {
44042c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn            throw new RuntimeException(
44142c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                    "Your content must have a ListView whose id attribute is " +
44242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn                    "'android.R.id.list'");
44342c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        }
444014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck        mList.setOnKeyListener(mListOnKeyListener);
44542c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn        mHandler.post(mRequestFocus);
44642c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn    }
447014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck
448014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck    private OnKeyListener mListOnKeyListener = new OnKeyListener() {
449014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck
450014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck        @Override
451014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck        public boolean onKey(View v, int keyCode, KeyEvent event) {
452014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck            Object selectedItem = mList.getSelectedItem();
453014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck            if (selectedItem instanceof Preference) {
454014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck                View selectedView = mList.getSelectedView();
455014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck                return ((Preference)selectedItem).onKey(
456014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck                        selectedView, keyCode, event);
457014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck            }
458014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck            return false;
459014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck        }
460014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck
461014fea2a663ab0bc2d80a6293b84b2647a4a1895John Reck    };
46242c2936f3c6e048caafb17eb9fe91fa4a33c8b86Dianne Hackborn}
463