19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.preference;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Collections;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.preference.Preference.OnPreferenceChangeInternalListener;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewGroup;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.widget.Adapter;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.widget.BaseAdapter;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.widget.ListView;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * An adapter that returns the {@link Preference} contained in this group.
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * In most cases, this adapter should be the base class for any custom
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * adapters from {@link Preference#getAdapter()}.
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This adapter obeys the
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Preference}'s adapter rule (the
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Adapter#getView(int, View, ViewGroup)} should be used instead of
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Preference#getView(ViewGroup)} if a {@link Preference} has an
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * adapter via {@link Preference#getAdapter()}).
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This adapter also propagates data change/invalidated notifications upward.
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This adapter does not include this {@link PreferenceGroup} in the returned
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * adapter, use {@link PreferenceCategoryAdapter} instead.
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see PreferenceCategoryAdapter
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeInternalListener {
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = "PreferenceGroupAdapter";
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The group that we are providing data from.
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private PreferenceGroup mPreferenceGroup;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Maps a position into this adapter -> {@link Preference}. These
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link Preference}s don't have to be direct children of this
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link PreferenceGroup}, they can be grand children or younger)
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private List<Preference> mPreferenceList;
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * List of unique Preference and its subclasses' names. This is used to find
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * out how many types of views this adapter can return. Once the count is
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * returned, this cannot be modified (since the ListView only checks the
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * count once--when the adapter is being set). We will not recycle views for
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Preference subclasses seen after the count has been returned.
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
72a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani    private ArrayList<PreferenceLayout> mPreferenceLayouts;
73a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani
74a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani    private PreferenceLayout mTempPreferenceLayout = new PreferenceLayout();
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Blocks the mPreferenceClassNames from being changed anymore.
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mHasReturnedViewTypeCount = false;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private volatile boolean mIsSyncing = false;
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Handler mHandler = new Handler();
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Runnable mSyncRunnable = new Runnable() {
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void run() {
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            syncMyPreferences();
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
91a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani    private static class PreferenceLayout implements Comparable<PreferenceLayout> {
92a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        private int resId;
93a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        private int widgetResId;
94a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        private String name;
95a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani
96a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        public int compareTo(PreferenceLayout other) {
97a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani            int compareNames = name.compareTo(other.name);
98a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani            if (compareNames == 0) {
99a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani                if (resId == other.resId) {
100a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani                    if (widgetResId == other.widgetResId) {
101a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani                        return 0;
102a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani                    } else {
103a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani                        return widgetResId - other.widgetResId;
104a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani                    }
105a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani                } else {
106a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani                    return resId - other.resId;
107a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani                }
108a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani            } else {
109a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani                return compareNames;
110a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani            }
111a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        }
112a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani    }
113a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PreferenceGroupAdapter(PreferenceGroup preferenceGroup) {
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPreferenceGroup = preferenceGroup;
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If this group gets or loses any children, let us know
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPreferenceGroup.setOnPreferenceChangeInternalListener(this);
118a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPreferenceList = new ArrayList<Preference>();
120a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        mPreferenceLayouts = new ArrayList<PreferenceLayout>();
121a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        syncMyPreferences();
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void syncMyPreferences() {
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized(this) {
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mIsSyncing) {
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
130a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIsSyncing = true;
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        List<Preference> newPreferenceList = new ArrayList<Preference>(mPreferenceList.size());
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flattenPreferenceGroup(newPreferenceList, mPreferenceGroup);
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPreferenceList = newPreferenceList;
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        notifyDataSetChanged();
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized(this) {
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIsSyncing = false;
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            notifyAll();
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void flattenPreferenceGroup(List<Preference> preferences, PreferenceGroup group) {
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // TODO: shouldn't always?
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        group.sortPreferences();
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int groupSize = group.getPreferenceCount();
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < groupSize; i++) {
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final Preference preference = group.getPreference(i);
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            preferences.add(preference);
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
156a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani            if (!mHasReturnedViewTypeCount && !preference.hasSpecifiedLayout()) {
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                addPreferenceClassName(preference);
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (preference instanceof PreferenceGroup) {
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final PreferenceGroup preferenceAsGroup = (PreferenceGroup) preference;
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (preferenceAsGroup.isOnSameScreenAsChildren()) {
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    flattenPreferenceGroup(preferences, preferenceAsGroup);
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            preference.setOnPreferenceChangeInternalListener(this);
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
171a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani    /**
172a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani     * Creates a string that includes the preference name, layout id and widget layout id.
173a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani     * If a particular preference type uses 2 different resources, they will be treated as
174a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani     * different view types.
175a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani     */
176a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani    private PreferenceLayout createPreferenceLayout(Preference preference, PreferenceLayout in) {
177a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        PreferenceLayout pl = in != null? in : new PreferenceLayout();
178a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        pl.name = preference.getClass().getName();
179a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        pl.resId = preference.getLayoutResource();
180a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        pl.widgetResId = preference.getWidgetLayoutResource();
181a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        return pl;
182a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani    }
183a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void addPreferenceClassName(Preference preference) {
185a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        final PreferenceLayout pl = createPreferenceLayout(preference, null);
186a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        int insertPos = Collections.binarySearch(mPreferenceLayouts, pl);
187a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Only insert if it doesn't exist (when it is negative).
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (insertPos < 0) {
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Convert to insert index
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            insertPos = insertPos * -1 - 1;
192a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani            mPreferenceLayouts.add(insertPos, pl);
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getCount() {
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mPreferenceList.size();
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Preference getItem(int position) {
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (position < 0 || position >= getCount()) return null;
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mPreferenceList.get(position);
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public long getItemId(int position) {
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (position < 0 || position >= getCount()) return ListView.INVALID_ROW_ID;
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this.getItem(position).getId();
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View getView(int position, View convertView, ViewGroup parent) {
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Preference preference = this.getItem(position);
212a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        // Build a PreferenceLayout to compare with known ones that are cacheable.
213a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        mTempPreferenceLayout = createPreferenceLayout(preference, mTempPreferenceLayout);
214a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani
215a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        // If it's not one of the cached ones, set the convertView to null so that
216a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        // the layout gets re-created by the Preference.
217a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        if (Collections.binarySearch(mPreferenceLayouts, mTempPreferenceLayout) < 0) {
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            convertView = null;
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
220a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return preference.getView(convertView, parent);
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isEnabled(int position) {
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (position < 0 || position >= getCount()) return true;
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this.getItem(position).isSelectable();
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean areAllItemsEnabled() {
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // There should always be a preference group, and these groups are always
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // disabled
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onPreferenceChange(Preference preference) {
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        notifyDataSetChanged();
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onPreferenceHierarchyChange(Preference preference) {
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler.removeCallbacks(mSyncRunnable);
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler.post(mSyncRunnable);
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean hasStableIds() {
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getItemViewType(int position) {
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mHasReturnedViewTypeCount) {
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHasReturnedViewTypeCount = true;
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Preference preference = this.getItem(position);
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (preference.hasSpecifiedLayout()) {
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return IGNORE_ITEM_VIEW_TYPE;
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
262a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        mTempPreferenceLayout = createPreferenceLayout(preference, mTempPreferenceLayout);
263a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani
264a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        int viewType = Collections.binarySearch(mPreferenceLayouts, mTempPreferenceLayout);
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (viewType < 0) {
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // This is a class that was seen after we returned the count, so
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // don't recycle it.
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return IGNORE_ITEM_VIEW_TYPE;
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return viewType;
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getViewTypeCount() {
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mHasReturnedViewTypeCount) {
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHasReturnedViewTypeCount = true;
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
280a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani        return Math.max(1, mPreferenceLayouts.size());
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
284