PreferenceGroup.java revision e61b4475e1837034d8926593aff9d35f8dfaebe2
16904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler/*
26904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Copyright (C) 2015 The Android Open Source Project
36904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler *
46904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Licensed under the Apache License, Version 2.0 (the "License");
56904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * you may not use this file except in compliance with the License.
66904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * You may obtain a copy of the License at
76904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler *
86904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler *      http://www.apache.org/licenses/LICENSE-2.0
96904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler *
106904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Unless required by applicable law or agreed to in writing, software
116904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * distributed under the License is distributed on an "AS IS" BASIS,
126904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * See the License for the specific language governing permissions and
146904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * limitations under the License
156904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */
166904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
176904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerpackage android.support.v7.preference;
186904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
196904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.content.Context;
206904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.content.res.TypedArray;
216904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.os.Bundle;
2284765eaea7da18d0576db557959129e9d0db8e8cTony Mantlerimport android.support.v4.content.res.TypedArrayUtils;
236904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.text.TextUtils;
246904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.util.AttributeSet;
256904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
266904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport java.util.ArrayList;
276904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport java.util.Collections;
286904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport java.util.List;
296904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
306904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler/**
316904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * A container for multiple
326904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * {@link Preference} objects. It is a base class for  Preference objects that are
336904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * parents, such as {@link PreferenceCategory} and {@link PreferenceScreen}.
346904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler *
356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <div class="special reference">
366904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <h3>Developer Guides</h3>
376904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * <p>For information about building a settings UI with Preferences,
386904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * read the <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a>
396904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * guide.</p>
406904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * </div>
416904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler *
426904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * @attr ref android.R.styleable#PreferenceGroup_orderingFromXml
436904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */
446904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerpublic abstract class PreferenceGroup extends Preference {
456904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
466904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * The container for child {@link Preference}s. This is sorted based on the
476904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * ordering, please use {@link #addPreference(Preference)} instead of adding
486904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * to this directly.
496904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
506904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    private List<Preference> mPreferenceList;
516904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
526904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    private boolean mOrderingAsAdded = true;
536904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
546904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    private int mCurrentPreferenceOrder = 0;
556904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
56e61b4475e1837034d8926593aff9d35f8dfaebe2Tony Mantler    private boolean mAttachedToHierarchy = false;
576904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
586904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public PreferenceGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
596904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        super(context, attrs, defStyleAttr, defStyleRes);
606904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
616904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        mPreferenceList = new ArrayList<>();
626904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
636904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        final TypedArray a = context.obtainStyledAttributes(
646904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                attrs, R.styleable.PreferenceGroup, defStyleAttr, defStyleRes);
6584765eaea7da18d0576db557959129e9d0db8e8cTony Mantler
6684765eaea7da18d0576db557959129e9d0db8e8cTony Mantler        mOrderingAsAdded =
6784765eaea7da18d0576db557959129e9d0db8e8cTony Mantler                TypedArrayUtils.getBoolean(a, R.styleable.PreferenceGroup_orderingFromXml,
6884765eaea7da18d0576db557959129e9d0db8e8cTony Mantler                        R.styleable.PreferenceGroup_orderingFromXml, true);
6984765eaea7da18d0576db557959129e9d0db8e8cTony Mantler
706904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        a.recycle();
716904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
726904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
736904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public PreferenceGroup(Context context, AttributeSet attrs, int defStyleAttr) {
746904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        this(context, attrs, defStyleAttr, 0);
756904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
766904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
776904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public PreferenceGroup(Context context, AttributeSet attrs) {
786904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        this(context, attrs, 0);
796904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
806904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
816904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
826904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Whether to order the {@link Preference} children of this group as they
836904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * are added. If this is false, the ordering will follow each Preference
846904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * order and default to alphabetic for those without an order.
856904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * <p>
866904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * If this is called after preferences are added, they will not be
876904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * re-ordered in the order they were added, hence call this method early on.
886904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     *
896904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @param orderingAsAdded Whether to order according to the order added.
906904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @see Preference#setOrder(int)
916904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
926904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public void setOrderingAsAdded(boolean orderingAsAdded) {
936904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        mOrderingAsAdded = orderingAsAdded;
946904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
956904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
966904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
976904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Whether this group is ordering preferences in the order they are added.
986904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     *
996904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @return Whether this group orders based on the order the children are added.
1006904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @see #setOrderingAsAdded(boolean)
1016904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
1026904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public boolean isOrderingAsAdded() {
1036904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        return mOrderingAsAdded;
1046904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
1056904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1066904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
1076904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Called by the inflater to add an item to this group.
1086904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
1096904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public void addItemFromInflater(Preference preference) {
1106904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        addPreference(preference);
1116904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
1126904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1136904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
1146904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Returns the number of children {@link Preference}s.
1156904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @return The number of preference children in this group.
1166904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
1176904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public int getPreferenceCount() {
1186904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        return mPreferenceList.size();
1196904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
1206904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1216904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
1226904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Returns the {@link Preference} at a particular index.
1236904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     *
1246904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @param index The index of the {@link Preference} to retrieve.
1256904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @return The {@link Preference}.
1266904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
1276904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public Preference getPreference(int index) {
1286904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        return mPreferenceList.get(index);
1296904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
1306904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1316904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
1326904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Adds a {@link Preference} at the correct position based on the
1336904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * preference's order.
1346904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     *
1356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @param preference The preference to add.
1366904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @return Whether the preference is now in this group.
1376904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
1386904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public boolean addPreference(Preference preference) {
1396904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        if (mPreferenceList.contains(preference)) {
1406904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            // Exists
1416904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            return true;
1426904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
1436904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1446904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        if (preference.getOrder() == DEFAULT_ORDER) {
1456904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            if (mOrderingAsAdded) {
1466904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                preference.setOrder(mCurrentPreferenceOrder++);
1476904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            }
1486904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1496904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            if (preference instanceof PreferenceGroup) {
1506904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                // TODO: fix (method is called tail recursively when inflating,
1516904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                // so we won't end up properly passing this flag down to children
1526904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                ((PreferenceGroup)preference).setOrderingAsAdded(mOrderingAsAdded);
1536904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            }
1546904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
1556904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1566904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        int insertionIndex = Collections.binarySearch(mPreferenceList, preference);
1576904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        if (insertionIndex < 0) {
1586904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            insertionIndex = insertionIndex * -1 - 1;
1596904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
1606904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1616904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        if (!onPrepareAddPreference(preference)) {
1626904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            return false;
1636904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
1646904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1656904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        synchronized(this) {
1666904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            mPreferenceList.add(insertionIndex, preference);
1676904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
1686904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1696904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        preference.onAttachedToHierarchy(getPreferenceManager());
1706904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
171e61b4475e1837034d8926593aff9d35f8dfaebe2Tony Mantler        if (mAttachedToHierarchy) {
1726904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            preference.onAttached();
1736904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
1746904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1756904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        notifyHierarchyChanged();
1766904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1776904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        return true;
1786904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
1796904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1806904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
1816904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Removes a {@link Preference} from this group.
1826904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     *
1836904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @param preference The preference to remove.
1846904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @return Whether the preference was found and removed.
1856904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
1866904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public boolean removePreference(Preference preference) {
1876904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        final boolean returnValue = removePreferenceInt(preference);
1886904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        notifyHierarchyChanged();
1896904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        return returnValue;
1906904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
1916904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1926904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    private boolean removePreferenceInt(Preference preference) {
1936904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        synchronized(this) {
1946904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            preference.onPrepareForRemoval();
1956904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            return mPreferenceList.remove(preference);
1966904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
1976904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
1986904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1996904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
2006904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Removes all {@link Preference Preferences} from this group.
2016904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
2026904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public void removeAll() {
2036904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        synchronized(this) {
2046904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            List<Preference> preferenceList = mPreferenceList;
2056904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            for (int i = preferenceList.size() - 1; i >= 0; i--) {
2066904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                removePreferenceInt(preferenceList.get(0));
2076904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            }
2086904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
2096904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        notifyHierarchyChanged();
2106904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
2116904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2126904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
2136904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Prepares a {@link Preference} to be added to the group.
2146904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     *
2156904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @param preference The preference to add.
2166904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @return Whether to allow adding the preference (true), or not (false).
2176904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
2186904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    protected boolean onPrepareAddPreference(Preference preference) {
2196904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        preference.onParentChanged(this, shouldDisableDependents());
2206904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        return true;
2216904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
2226904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2236904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
2246904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Finds a {@link Preference} based on its key. If two {@link Preference}
2256904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * share the same key (not recommended), the first to appear will be
2266904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * returned (to retrieve the other preference with the same key, call this
2276904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * method on the first preference). If this preference has the key, it will
2286904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * not be returned.
2296904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * <p>
2306904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * This will recursively search for the preference into children that are
2316904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * also {@link PreferenceGroup PreferenceGroups}.
2326904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     *
2336904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @param key The key of the preference to retrieve.
2346904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @return The {@link Preference} with the key, or null.
2356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
2366904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public Preference findPreference(CharSequence key) {
2376904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        if (TextUtils.equals(getKey(), key)) {
2386904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            return this;
2396904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
2406904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        final int preferenceCount = getPreferenceCount();
2416904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        for (int i = 0; i < preferenceCount; i++) {
2426904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            final Preference preference = getPreference(i);
2436904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            final String curKey = preference.getKey();
2446904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2456904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            if (curKey != null && curKey.equals(key)) {
2466904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                return preference;
2476904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            }
2486904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2496904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            if (preference instanceof PreferenceGroup) {
2506904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                final Preference returnedPreference = ((PreferenceGroup)preference)
2516904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                        .findPreference(key);
2526904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                if (returnedPreference != null) {
2536904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                    return returnedPreference;
2546904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                }
2556904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            }
2566904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
2576904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2586904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        return null;
2596904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
2606904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2616904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
2626904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Whether this preference group should be shown on the same screen as its
2636904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * contained preferences.
2646904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     *
2656904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @return True if the contained preferences should be shown on the same
2666904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     *         screen as this preference.
2676904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
2686904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    protected boolean isOnSameScreenAsChildren() {
2696904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        return true;
2706904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
2716904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2726904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    @Override
273e61b4475e1837034d8926593aff9d35f8dfaebe2Tony Mantler    public void onAttached() {
2746904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        super.onAttached();
2756904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2766904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        // Mark as attached so if a preference is later added to this group, we
2776904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        // can tell it we are already attached
278e61b4475e1837034d8926593aff9d35f8dfaebe2Tony Mantler        mAttachedToHierarchy = true;
2796904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2806904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        // Dispatch to all contained preferences
2816904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        final int preferenceCount = getPreferenceCount();
2826904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        for (int i = 0; i < preferenceCount; i++) {
2836904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            getPreference(i).onAttached();
2846904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
2856904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
2866904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2876904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    @Override
2886904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    protected void onPrepareForRemoval() {
2896904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        super.onPrepareForRemoval();
2906904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2916904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        // We won't be attached to the activity anymore
292e61b4475e1837034d8926593aff9d35f8dfaebe2Tony Mantler        mAttachedToHierarchy = false;
2936904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
2946904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2956904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    @Override
2966904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public void notifyDependencyChange(boolean disableDependents) {
2976904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        super.notifyDependencyChange(disableDependents);
2986904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2996904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        // Child preferences have an implicit dependency on their containing
3006904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        // group. Dispatch dependency change to all contained preferences.
3016904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        final int preferenceCount = getPreferenceCount();
3026904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        for (int i = 0; i < preferenceCount; i++) {
3036904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            getPreference(i).onParentChanged(this, disableDependents);
3046904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
3056904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
3066904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
3076904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    void sortPreferences() {
3086904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        synchronized (this) {
3096904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            Collections.sort(mPreferenceList);
3106904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
3116904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
3126904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
3136904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    @Override
3146904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    protected void dispatchSaveInstanceState(Bundle container) {
3156904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        super.dispatchSaveInstanceState(container);
3166904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
3176904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        // Dispatch to all contained preferences
3186904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        final int preferenceCount = getPreferenceCount();
3196904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        for (int i = 0; i < preferenceCount; i++) {
3206904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            getPreference(i).dispatchSaveInstanceState(container);
3216904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
3226904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
3236904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
3246904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    @Override
3256904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    protected void dispatchRestoreInstanceState(Bundle container) {
3266904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        super.dispatchRestoreInstanceState(container);
3276904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
3286904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        // Dispatch to all contained preferences
3296904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        final int preferenceCount = getPreferenceCount();
3306904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        for (int i = 0; i < preferenceCount; i++) {
3316904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            getPreference(i).dispatchRestoreInstanceState(container);
3326904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
3336904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
3346904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
3356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler}
336