PreferenceGroup.java revision 8f7f0d48fac8f83e90a04ba67f9a03f93c6ed262
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();
1958f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk            boolean success = mPreferenceList.remove(preference);
1968f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk            if (success) {
1978f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk                preference.onDetached();
1988f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk            }
1998f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk            return success;
2006904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
2016904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
2026904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2036904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
2046904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Removes all {@link Preference Preferences} from this group.
2056904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
2066904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public void removeAll() {
2076904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        synchronized(this) {
2086904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            List<Preference> preferenceList = mPreferenceList;
2096904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            for (int i = preferenceList.size() - 1; i >= 0; i--) {
2106904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                removePreferenceInt(preferenceList.get(0));
2116904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            }
2126904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
2136904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        notifyHierarchyChanged();
2146904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
2156904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2166904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
2176904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Prepares a {@link Preference} to be added to the group.
2186904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     *
2196904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @param preference The preference to add.
2206904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @return Whether to allow adding the preference (true), or not (false).
2216904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
2226904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    protected boolean onPrepareAddPreference(Preference preference) {
2236904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        preference.onParentChanged(this, shouldDisableDependents());
2246904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        return true;
2256904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
2266904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2276904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
2286904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Finds a {@link Preference} based on its key. If two {@link Preference}
2296904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * share the same key (not recommended), the first to appear will be
2306904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * returned (to retrieve the other preference with the same key, call this
2316904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * method on the first preference). If this preference has the key, it will
2326904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * not be returned.
2336904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * <p>
2346904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * This will recursively search for the preference into children that are
2356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * also {@link PreferenceGroup PreferenceGroups}.
2366904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     *
2376904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @param key The key of the preference to retrieve.
2386904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @return The {@link Preference} with the key, or null.
2396904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
2406904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public Preference findPreference(CharSequence key) {
2416904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        if (TextUtils.equals(getKey(), key)) {
2426904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            return this;
2436904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
2446904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        final int preferenceCount = getPreferenceCount();
2456904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        for (int i = 0; i < preferenceCount; i++) {
2466904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            final Preference preference = getPreference(i);
2476904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            final String curKey = preference.getKey();
2486904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2496904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            if (curKey != null && curKey.equals(key)) {
2506904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                return preference;
2516904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            }
2526904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2536904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            if (preference instanceof PreferenceGroup) {
2546904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                final Preference returnedPreference = ((PreferenceGroup)preference)
2556904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                        .findPreference(key);
2566904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                if (returnedPreference != null) {
2576904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                    return returnedPreference;
2586904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                }
2596904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            }
2606904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
2616904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2626904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        return null;
2636904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
2646904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2656904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
2666904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Whether this preference group should be shown on the same screen as its
2676904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * contained preferences.
2686904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     *
2696904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @return True if the contained preferences should be shown on the same
2706904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     *         screen as this preference.
2716904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
2726904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    protected boolean isOnSameScreenAsChildren() {
2736904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        return true;
2746904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
2756904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2766904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    @Override
277e61b4475e1837034d8926593aff9d35f8dfaebe2Tony Mantler    public void onAttached() {
2786904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        super.onAttached();
2796904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2806904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        // Mark as attached so if a preference is later added to this group, we
2816904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        // can tell it we are already attached
282e61b4475e1837034d8926593aff9d35f8dfaebe2Tony Mantler        mAttachedToHierarchy = true;
2836904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2846904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        // Dispatch to all contained preferences
2856904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        final int preferenceCount = getPreferenceCount();
2866904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        for (int i = 0; i < preferenceCount; i++) {
2876904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            getPreference(i).onAttached();
2886904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
2896904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
2906904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2916904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    @Override
2928f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk    public void onDetached() {
2938f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk        super.onDetached();
2946904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
2956904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        // We won't be attached to the activity anymore
296e61b4475e1837034d8926593aff9d35f8dfaebe2Tony Mantler        mAttachedToHierarchy = false;
2978f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk
2988f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk        // Dispatch to all contained preferences
2998f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk        final int preferenceCount = getPreferenceCount();
3008f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk        for (int i = 0; i < preferenceCount; i++) {
3018f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk            getPreference(i).onDetached();
3028f7f0d48fac8f83e90a04ba67f9a03f93c6ed262Jason Monk        }
3036904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
3046904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
3056904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    @Override
3066904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public void notifyDependencyChange(boolean disableDependents) {
3076904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        super.notifyDependencyChange(disableDependents);
3086904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
3096904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        // Child preferences have an implicit dependency on their containing
3106904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        // group. Dispatch dependency change to all contained preferences.
3116904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        final int preferenceCount = getPreferenceCount();
3126904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        for (int i = 0; i < preferenceCount; i++) {
3136904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            getPreference(i).onParentChanged(this, disableDependents);
3146904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
3156904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
3166904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
3176904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    void sortPreferences() {
3186904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        synchronized (this) {
3196904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            Collections.sort(mPreferenceList);
3206904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
3216904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
3226904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
3236904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    @Override
3246904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    protected void dispatchSaveInstanceState(Bundle container) {
3256904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        super.dispatchSaveInstanceState(container);
3266904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
3276904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        // Dispatch to all contained preferences
3286904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        final int preferenceCount = getPreferenceCount();
3296904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        for (int i = 0; i < preferenceCount; i++) {
3306904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            getPreference(i).dispatchSaveInstanceState(container);
3316904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
3326904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
3336904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
3346904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    @Override
3356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    protected void dispatchRestoreInstanceState(Bundle container) {
3366904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        super.dispatchRestoreInstanceState(container);
3376904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
3386904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        // Dispatch to all contained preferences
3396904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        final int preferenceCount = getPreferenceCount();
3406904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        for (int i = 0; i < preferenceCount; i++) {
3416904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            getPreference(i).dispatchRestoreInstanceState(container);
3426904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
3436904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
3446904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
3456904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler}
346