Subclasses:
PreferenceScreen, PreferenceCategory
Gradle dependencies
compile group: 'androidx.preference', name: 'preference', version: '1.2.0'
- groupId: androidx.preference
- artifactId: preference
- version: 1.2.0
Artifact androidx.preference:preference:1.2.0 it located at Google repository (https://maven.google.com/)
Androidx artifact mapping:
androidx.preference:preference com.android.support:preference-v7
Androidx class mapping:
androidx.preference.PreferenceGroup android.support.v7.preference.PreferenceGroup
Overview
A container for multiple Preferences. It is a base class for preference
objects that are parents, such as PreferenceCategory and PreferenceScreen.
Developer Guides
For information about building a settings screen using the AndroidX Preference library, see
Settings.
Summary
Constructors |
---|
public | PreferenceGroup(Context context, AttributeSet attrs)
|
public | PreferenceGroup(Context context, AttributeSet attrs, int defStyleAttr)
|
public | PreferenceGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
|
Methods |
---|
public void | addItemFromInflater(Preference preference)
Called by the inflater to add an item to this group. |
public boolean | addPreference(Preference preference)
Adds a Preference at the correct position based on the preference's order. |
void | dispatchRestoreInstanceState(Bundle container)
Called by Preference.restoreHierarchyState(Bundle) to retrieve the saved state for this preference
and its children. |
void | dispatchSaveInstanceState(Bundle container)
Called by Preference.saveHierarchyState(Bundle) to store the instance for this preference and its
children. |
public Preference | findPreference(java.lang.CharSequence key)
Finds a Preference based on its key. |
public int | getInitialExpandedChildrenCount()
Gets the maximal number of children that are initially shown. |
public PreferenceGroup.OnExpandButtonClickListener | getOnExpandButtonClickListener()
Returns the callback to be invoked when the expand button is clicked. |
public Preference | getPreference(int index)
Returns the Preference at a particular index. |
public int | getPreferenceCount()
Returns the number of children Preferences. |
public boolean | isAttached()
Returns true if we're between PreferenceGroup.onAttached() and Preference.onPrepareForRemoval() |
protected boolean | isOnSameScreenAsChildren()
Whether this preference group should be shown on the same screen as its contained
preferences. |
public boolean | isOrderingAsAdded()
Whether this group is ordering preferences in the order they are added. |
public void | notifyDependencyChange(boolean disableDependents)
Notifies any listening dependents of a change that affects the dependency. |
public void | onAttached()
Called when the preference hierarchy has been attached to the list of preferences. |
public void | onDetached()
Called when the preference hierarchy has been detached from the list of preferences. |
protected boolean | onPrepareAddPreference(Preference preference)
Prepares a Preference to be added to the group. |
protected void | onRestoreInstanceState(Parcelable state)
Hook allowing a preference to re-apply a representation of its internal state that had
previously been generated by Preference.onSaveInstanceState(). |
protected Parcelable | onSaveInstanceState()
Hook allowing a preference to generate a representation of its internal state that can
later be used to create a new instance with that same state. |
public void | removeAll()
Removes all Preferences from this group. |
public boolean | removePreference(Preference preference)
Removes a Preference from this group. |
public boolean | removePreferenceRecursively(java.lang.CharSequence key)
Recursively finds and removes a Preference from this group or a nested group lower
down in the hierarchy. |
public void | setInitialExpandedChildrenCount(int expandedCount)
Sets the maximal number of children that are shown when the preference group is launched
where the rest of the children will be hidden. |
public void | setOnExpandButtonClickListener(PreferenceGroup.OnExpandButtonClickListener onExpandButtonClickListener)
Sets the callback to be invoked when the expand button is clicked. |
public void | setOrderingAsAdded(boolean orderingAsAdded)
Whether to order the Preference children of this group as they are added. |
from Preference | callChangeListener, compareTo, findPreferenceInHierarchy, getContext, getDependency, getExtras, getFragment, getIcon, getIntent, getKey, getLayoutResource, getOnPreferenceChangeListener, getOnPreferenceClickListener, getOrder, getParent, getPersistedBoolean, getPersistedFloat, getPersistedInt, getPersistedLong, getPersistedString, getPersistedStringSet, getPreferenceDataStore, getPreferenceManager, getSharedPreferences, getShouldDisableView, getSummary, getSummaryProvider, getTitle, getWidgetLayoutResource, hasKey, isCopyingEnabled, isEnabled, isIconSpaceReserved, isPersistent, isSelectable, isShown, isSingleLineTitle, isVisible, notifyChanged, notifyHierarchyChanged, onAttachedToHierarchy, onAttachedToHierarchy, onBindViewHolder, onClick, onDependencyChanged, onGetDefaultValue, onInitializeAccessibilityNodeInfo, onParentChanged, onPrepareForRemoval, onSetInitialValue, onSetInitialValue, peekExtras, performClick, performClick, persistBoolean, persistFloat, persistInt, persistLong, persistString, persistStringSet, restoreHierarchyState, saveHierarchyState, setCopyingEnabled, setDefaultValue, setDependency, setEnabled, setFragment, setIcon, setIconSpaceReserved, setIntent, setKey, setLayoutResource, setOnPreferenceChangeListener, setOnPreferenceClickListener, setOrder, setPersistent, setPreferenceDataStore, setSelectable, setShouldDisableView, setSingleLineTitle, setSummary, setSummary, setSummaryProvider, setTitle, setTitle, setViewId, setVisible, setWidgetLayoutResource, shouldDisableDependents, shouldPersist, toString |
from java.lang.Object | clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Constructors
public
PreferenceGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
public
PreferenceGroup(Context context, AttributeSet attrs, int defStyleAttr)
public
PreferenceGroup(Context context, AttributeSet attrs)
Methods
public void
setOrderingAsAdded(boolean orderingAsAdded)
Whether to order the Preference children of this group as they are added. If this
is false, the ordering will follow each Preference order and default to alphabetic for
those without an order.
If this is called after preferences are added, they will not be re-ordered in the
order they were added, hence call this method early on.
Parameters:
orderingAsAdded: Whether to order according to the order added
See also: Preference.setOrder(int)
public boolean
isOrderingAsAdded()
Whether this group is ordering preferences in the order they are added.
Returns:
Whether this group orders based on the order the children are added
See also: PreferenceGroup.setOrderingAsAdded(boolean)
public void
setInitialExpandedChildrenCount(int expandedCount)
Sets the maximal number of children that are shown when the preference group is launched
where the rest of the children will be hidden. If some children are hidden an expand
button will be provided to show all the hidden children. Any child in any level of the
hierarchy that is also a preference group (e.g. preference category) will not be counted
towards the limit. But instead the children of such group will be counted. By default, all
children will be shown, so the default value of this attribute is equal to Integer.MAX_VALUE.
Note: The group should have a key defined if an expandable preference is present to
correctly persist state.
Parameters:
expandedCount: The number of children that is initially shown
public int
getInitialExpandedChildrenCount()
Gets the maximal number of children that are initially shown.
Returns:
The maximal number of children that are initially shown
public void
addItemFromInflater(
Preference preference)
Called by the inflater to add an item to this group.
public int
getPreferenceCount()
Returns the number of children Preferences.
Returns:
The number of preference children in this group
Returns the Preference at a particular index.
Parameters:
index: The index of the Preference to retrieve
Returns:
The Preference
public boolean
addPreference(
Preference preference)
Adds a Preference at the correct position based on the preference's order.
Parameters:
preference: The preference to add
Returns:
Whether the preference is now in this group
public boolean
removePreference(
Preference preference)
Removes a Preference from this group.
Note: This action is not recursive, and will only remove a preference if it exists in
this group, ignoring preferences found in nested groups. Use
PreferenceGroup.removePreferenceRecursively(CharSequence) to recursively find and remove a
preference.
Parameters:
preference: The preference to remove
Returns:
Whether the preference was found and removed
See also: PreferenceGroup.removePreferenceRecursively(CharSequence)
public boolean
removePreferenceRecursively(java.lang.CharSequence key)
Recursively finds and removes a Preference from this group or a nested group lower
down in the hierarchy. If two Preferences share the same key (not recommended),
the first to appear will be removed.
Parameters:
key: The key of the preference to remove
Returns:
Whether the preference was found and removed
See also: PreferenceGroup.findPreference(CharSequence)
Removes all Preferences from this group.
protected boolean
onPrepareAddPreference(
Preference preference)
Prepares a Preference to be added to the group.
Parameters:
preference: The preference to add
Returns:
Whether to allow adding the preference (true), or not (false)
public
Preference findPreference(java.lang.CharSequence key)
Finds a Preference based on its key. If two Preferences share the same key
(not recommended), the first to appear will be returned.
This will recursively search for the Preference in any children that are also
PreferenceGroups.
Parameters:
key: The key of the Preference to retrieve
Returns:
The Preference with the key, or null
protected boolean
isOnSameScreenAsChildren()
Whether this preference group should be shown on the same screen as its contained
preferences.
Returns:
true if the contained preferences should be shown on the same screen as this
preference.
public boolean
isAttached()
Returns true if we're between PreferenceGroup.onAttached() and Preference.onPrepareForRemoval()
Sets the callback to be invoked when the expand button is clicked.
Used by Settings.
Parameters:
onExpandButtonClickListener: The callback to be invoked
See also: PreferenceGroup.setInitialExpandedChildrenCount(int)
Returns the callback to be invoked when the expand button is clicked.
Used by Settings.
Returns:
The callback to be invoked when the expand button is clicked.
Called when the preference hierarchy has been attached to the list of preferences. This
can also be called when this preference has been attached to a group that was already
attached to the list of preferences.
Called when the preference hierarchy has been detached from the list of preferences. This
can also be called when this preference has been removed from a group that was attached to
the list of preferences.
public void
notifyDependencyChange(boolean disableDependents)
Notifies any listening dependents of a change that affects the dependency.
Parameters:
disableDependents: Whether this preference should disable
its dependents.
void
dispatchSaveInstanceState(Bundle container)
Called by Preference.saveHierarchyState(Bundle) to store the instance for this preference and its
children. May be overridden to modify how the save happens for children. For example, some
preference objects may want to not store an instance for their children.
Parameters:
container: The Bundle in which to save the instance of this preference
See also: Preference.saveHierarchyState(Bundle), Preference.onSaveInstanceState()
void
dispatchRestoreInstanceState(Bundle container)
Called by Preference.restoreHierarchyState(Bundle) to retrieve the saved state for this preference
and its children. May be overridden to modify how restoring happens to the children of a
preference. For example, some preference objects may not want to save state for their
children.
Parameters:
container: The Bundle that holds the previously saved state
See also: Preference.restoreHierarchyState(Bundle), Preference.onRestoreInstanceState(Parcelable)
protected Parcelable
onSaveInstanceState()
Hook allowing a preference to generate a representation of its internal state that can
later be used to create a new instance with that same state. This state should only
contain information that is not persistent or can be reconstructed later.
Returns:
A Parcelable object containing the current dynamic state of this preference, or
null if there is nothing interesting to save. The default implementation returns
null.
See also: Preference.onRestoreInstanceState(Parcelable), Preference.saveHierarchyState(Bundle)
protected void
onRestoreInstanceState(Parcelable state)
Hook allowing a preference to re-apply a representation of its internal state that had
previously been generated by Preference.onSaveInstanceState(). This function will never be
called with a null state.
Parameters:
state: The saved state that had previously been returned by
Preference.onSaveInstanceState().
See also: Preference.onSaveInstanceState(), Preference.restoreHierarchyState(Bundle)
Source
/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.preference;
import static androidx.annotation.RestrictTo.Scope.LIBRARY;
import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.collection.SimpleArrayMap;
import androidx.core.content.res.TypedArrayUtils;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* A container for multiple {@link Preference}s. It is a base class for preference
* objects that are parents, such as {@link PreferenceCategory} and {@link PreferenceScreen}.
*
* <div class="special reference">
* <h3>Developer Guides</h3>
* <p>For information about building a settings screen using the AndroidX Preference library, see
* <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a>.</p>
* </div>
*
* @attr name android:orderingFromXml
* @attr name initialExpandedChildrenCount
*/
public abstract class PreferenceGroup extends Preference {
private static final String TAG = "PreferenceGroup";
@SuppressWarnings("WeakerAccess") /* synthetic access */
final SimpleArrayMap<String, Long> mIdRecycleCache = new SimpleArrayMap<>();
private final Handler mHandler = new Handler(Looper.getMainLooper());
/**
* The container for child {@link Preference}s. This is sorted based on the ordering, please
* use {@link #addPreference(Preference)} instead of adding to this directly.
*/
private final List<Preference> mPreferences;
private boolean mOrderingAsAdded = true;
private int mCurrentPreferenceOrder = 0;
private boolean mAttachedToHierarchy = false;
private int mInitialExpandedChildrenCount = Integer.MAX_VALUE;
private OnExpandButtonClickListener mOnExpandButtonClickListener = null;
private final Runnable mClearRecycleCacheRunnable = new Runnable() {
@Override
public void run() {
synchronized (this) {
mIdRecycleCache.clear();
}
}
};
public PreferenceGroup(@NonNull Context context, @Nullable AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
mPreferences = new ArrayList<>();
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.PreferenceGroup, defStyleAttr, defStyleRes);
mOrderingAsAdded =
TypedArrayUtils.getBoolean(a, R.styleable.PreferenceGroup_orderingFromXml,
R.styleable.PreferenceGroup_orderingFromXml, true);
if (a.hasValue(R.styleable.PreferenceGroup_initialExpandedChildrenCount)) {
setInitialExpandedChildrenCount(TypedArrayUtils.getInt(
a, R.styleable.PreferenceGroup_initialExpandedChildrenCount,
R.styleable.PreferenceGroup_initialExpandedChildrenCount, Integer.MAX_VALUE));
}
a.recycle();
}
public PreferenceGroup(@NonNull Context context, @Nullable AttributeSet attrs,
int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public PreferenceGroup(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
/**
* Whether to order the {@link Preference} children of this group as they are added. If this
* is false, the ordering will follow each Preference order and default to alphabetic for
* those without an order.
*
* <p>If this is called after preferences are added, they will not be re-ordered in the
* order they were added, hence call this method early on.
*
* @param orderingAsAdded Whether to order according to the order added
* @see Preference#setOrder(int)
*/
public void setOrderingAsAdded(boolean orderingAsAdded) {
mOrderingAsAdded = orderingAsAdded;
}
/**
* Whether this group is ordering preferences in the order they are added.
*
* @return Whether this group orders based on the order the children are added
* @see #setOrderingAsAdded(boolean)
*/
public boolean isOrderingAsAdded() {
return mOrderingAsAdded;
}
/**
* Sets the maximal number of children that are shown when the preference group is launched
* where the rest of the children will be hidden. If some children are hidden an expand
* button will be provided to show all the hidden children. Any child in any level of the
* hierarchy that is also a preference group (e.g. preference category) will not be counted
* towards the limit. But instead the children of such group will be counted. By default, all
* children will be shown, so the default value of this attribute is equal to Integer.MAX_VALUE.
*
* <p>Note: The group should have a key defined if an expandable preference is present to
* correctly persist state.
*
* @param expandedCount The number of children that is initially shown
* {@link androidx.preference.R.attr#initialExpandedChildrenCount}
*/
public void setInitialExpandedChildrenCount(int expandedCount) {
if (expandedCount != Integer.MAX_VALUE && !hasKey()) {
Log.e(TAG, getClass().getSimpleName()
+ " should have a key defined if it contains an expandable preference");
}
mInitialExpandedChildrenCount = expandedCount;
}
/**
* Gets the maximal number of children that are initially shown.
*
* @return The maximal number of children that are initially shown
* {@link androidx.preference.R.attr#initialExpandedChildrenCount}
*/
public int getInitialExpandedChildrenCount() {
return mInitialExpandedChildrenCount;
}
/**
* Called by the inflater to add an item to this group.
*/
public void addItemFromInflater(@NonNull Preference preference) {
addPreference(preference);
}
/**
* Returns the number of children {@link Preference}s.
*
* @return The number of preference children in this group
*/
public int getPreferenceCount() {
return mPreferences.size();
}
/**
* Returns the {@link Preference} at a particular index.
*
* @param index The index of the {@link Preference} to retrieve
* @return The {@link Preference}
*/
@NonNull
public Preference getPreference(int index) {
return mPreferences.get(index);
}
/**
* Adds a {@link Preference} at the correct position based on the preference's order.
*
* @param preference The preference to add
* @return Whether the preference is now in this group
*/
public boolean addPreference(@NonNull Preference preference) {
if (mPreferences.contains(preference)) {
return true;
}
if (preference.getKey() != null) {
PreferenceGroup root = this;
while (root.getParent() != null) {
root = root.getParent();
}
final String key = preference.getKey();
if (root.findPreference(key) != null) {
Log.e(TAG, "Found duplicated key: \"" + key
+ "\". This can cause unintended behaviour,"
+ " please use unique keys for every preference.");
}
}
if (preference.getOrder() == DEFAULT_ORDER) {
if (mOrderingAsAdded) {
preference.setOrder(mCurrentPreferenceOrder++);
}
if (preference instanceof PreferenceGroup) {
// TODO: fix (method is called tail recursively when inflating,
// so we won't end up properly passing this flag down to children
((PreferenceGroup) preference).setOrderingAsAdded(mOrderingAsAdded);
}
}
int insertionIndex = Collections.binarySearch(mPreferences, preference);
if (insertionIndex < 0) {
insertionIndex = insertionIndex * -1 - 1;
}
if (!onPrepareAddPreference(preference)) {
return false;
}
synchronized (this) {
mPreferences.add(insertionIndex, preference);
}
final PreferenceManager preferenceManager = getPreferenceManager();
final String key = preference.getKey();
final long id;
if (key != null && mIdRecycleCache.containsKey(key)) {
id = mIdRecycleCache.get(key);
mIdRecycleCache.remove(key);
} else {
id = preferenceManager.getNextId();
}
preference.onAttachedToHierarchy(preferenceManager, id);
preference.assignParent(this);
if (mAttachedToHierarchy) {
preference.onAttached();
}
notifyHierarchyChanged();
return true;
}
/**
* Removes a {@link Preference} from this group.
*
* <p>Note: This action is not recursive, and will only remove a preference if it exists in
* this group, ignoring preferences found in nested groups. Use
* {@link #removePreferenceRecursively(CharSequence)} to recursively find and remove a
* preference.
*
* @param preference The preference to remove
* @return Whether the preference was found and removed
* @see #removePreferenceRecursively(CharSequence)
*/
public boolean removePreference(@NonNull Preference preference) {
final boolean returnValue = removePreferenceInt(preference);
notifyHierarchyChanged();
return returnValue;
}
/**
* Recursively finds and removes a {@link Preference} from this group or a nested group lower
* down in the hierarchy. If two {@link Preference}s share the same key (not recommended),
* the first to appear will be removed.
*
* @param key The key of the preference to remove
* @return Whether the preference was found and removed
* @see #findPreference(CharSequence)
*/
public boolean removePreferenceRecursively(@NonNull CharSequence key) {
final Preference preference = findPreference(key);
if (preference == null) {
return false;
}
return preference.getParent().removePreference(preference);
}
private boolean removePreferenceInt(@NonNull Preference preference) {
synchronized (this) {
preference.onPrepareForRemoval();
if (preference.getParent() == this) {
preference.assignParent(null);
}
boolean success = mPreferences.remove(preference);
if (success) {
// If this preference, or another preference with the same key, gets re-added
// immediately, we want it to have the same id so that it can be correctly tracked
// in the adapter by RecyclerView, to make it appear as if it has only been
// seamlessly updated. If the preference is not re-added by the time the handler
// runs, we take that as a signal that the preference will not be re-added soon
// in which case it does not need to retain the same id.
// If two (or more) preferences have the same (or null) key and both are removed
// and then re-added, only one id will be recycled and the second (and later)
// preferences will receive a newly generated id. This use pattern of the preference
// API is strongly discouraged.
final String key = preference.getKey();
if (key != null) {
mIdRecycleCache.put(key, preference.getId());
mHandler.removeCallbacks(mClearRecycleCacheRunnable);
mHandler.post(mClearRecycleCacheRunnable);
}
if (mAttachedToHierarchy) {
preference.onDetached();
}
}
return success;
}
}
/**
* Removes all {@link Preference}s from this group.
*/
public void removeAll() {
synchronized (this) {
List<Preference> preferences = mPreferences;
for (int i = preferences.size() - 1; i >= 0; i--) {
removePreferenceInt(preferences.get(0));
}
}
notifyHierarchyChanged();
}
/**
* Prepares a {@link Preference} to be added to the group.
*
* @param preference The preference to add
* @return Whether to allow adding the preference ({@code true}), or not ({@code false})
*/
protected boolean onPrepareAddPreference(@NonNull Preference preference) {
preference.onParentChanged(this, shouldDisableDependents());
return true;
}
/**
* Finds a {@link Preference} based on its key. If two {@link Preference}s share the same key
* (not recommended), the first to appear will be returned.
*
* <p>This will recursively search for the {@link Preference} in any children that are also
* {@link PreferenceGroup}s.
*
* @param key The key of the {@link Preference} to retrieve
* @return The {@link Preference} with the key, or {@code null}
*/
@SuppressWarnings({"TypeParameterUnusedInFormals", "unchecked"})
@Nullable
public <T extends Preference> T findPreference(@NonNull CharSequence key) {
if (key == null) {
throw new IllegalArgumentException("Key cannot be null");
}
if (TextUtils.equals(getKey(), key)) {
return (T) this;
}
final int preferenceCount = getPreferenceCount();
for (int i = 0; i < preferenceCount; i++) {
final Preference preference = getPreference(i);
final String curKey = preference.getKey();
if (TextUtils.equals(curKey, key)) {
return (T) preference;
}
if (preference instanceof PreferenceGroup) {
final T returnedPreference = ((PreferenceGroup) preference).findPreference(key);
if (returnedPreference != null) {
return returnedPreference;
}
}
}
return null;
}
/**
* Whether this preference group should be shown on the same screen as its contained
* preferences.
*
* @return {@code true} if the contained preferences should be shown on the same screen as this
* preference.
*/
protected boolean isOnSameScreenAsChildren() {
return true;
}
/**
* Returns true if we're between {@link #onAttached()} and {@link #onPrepareForRemoval()}
*
* @hide
*/
@RestrictTo(LIBRARY)
public boolean isAttached() {
return mAttachedToHierarchy;
}
/**
* Sets the callback to be invoked when the expand button is clicked.
*
* Used by Settings.
*
* @param onExpandButtonClickListener The callback to be invoked
* @see #setInitialExpandedChildrenCount(int)
* @hide
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
public void setOnExpandButtonClickListener(
@Nullable OnExpandButtonClickListener onExpandButtonClickListener) {
mOnExpandButtonClickListener = onExpandButtonClickListener;
}
/**
* Returns the callback to be invoked when the expand button is clicked.
*
* Used by Settings.
*
* @return The callback to be invoked when the expand button is clicked.
* @hide
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
@Nullable
public OnExpandButtonClickListener getOnExpandButtonClickListener() {
return mOnExpandButtonClickListener;
}
@Override
public void onAttached() {
super.onAttached();
// Mark as attached so if a preference is later added to this group, we
// can tell it we are already attached
mAttachedToHierarchy = true;
// Dispatch to all contained preferences
final int preferenceCount = getPreferenceCount();
for (int i = 0; i < preferenceCount; i++) {
getPreference(i).onAttached();
}
}
@Override
public void onDetached() {
super.onDetached();
// We won't be attached to the activity anymore
mAttachedToHierarchy = false;
// Dispatch to all contained preferences
final int preferenceCount = getPreferenceCount();
for (int i = 0; i < preferenceCount; i++) {
getPreference(i).onDetached();
}
}
@Override
public void notifyDependencyChange(boolean disableDependents) {
super.notifyDependencyChange(disableDependents);
// Child preferences have an implicit dependency on their containing
// group. Dispatch dependency change to all contained preferences.
final int preferenceCount = getPreferenceCount();
for (int i = 0; i < preferenceCount; i++) {
getPreference(i).onParentChanged(this, disableDependents);
}
}
void sortPreferences() {
synchronized (this) {
Collections.sort(mPreferences);
}
}
@Override
protected void dispatchSaveInstanceState(@NonNull Bundle container) {
super.dispatchSaveInstanceState(container);
// Dispatch to all contained preferences
final int preferenceCount = getPreferenceCount();
for (int i = 0; i < preferenceCount; i++) {
getPreference(i).dispatchSaveInstanceState(container);
}
}
@Override
protected void dispatchRestoreInstanceState(@NonNull Bundle container) {
super.dispatchRestoreInstanceState(container);
// Dispatch to all contained preferences
final int preferenceCount = getPreferenceCount();
for (int i = 0; i < preferenceCount; i++) {
getPreference(i).dispatchRestoreInstanceState(container);
}
}
@NonNull
@Override
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
return new SavedState(superState, mInitialExpandedChildrenCount);
}
@Override
protected void onRestoreInstanceState(@Nullable Parcelable state) {
if (state == null || !state.getClass().equals(SavedState.class)) {
// Didn't save state for us in saveInstanceState
super.onRestoreInstanceState(state);
return;
}
SavedState groupState = (SavedState) state;
mInitialExpandedChildrenCount = groupState.mInitialExpandedChildrenCount;
super.onRestoreInstanceState(groupState.getSuperState());
}
/**
* Interface for PreferenceGroup adapters to implement so that
* {@link PreferenceFragmentCompat#scrollToPreference(String)} and
* {@link PreferenceFragmentCompat#scrollToPreference(Preference)}
* can determine the correct scroll position to request.
*/
public interface PreferencePositionCallback {
/**
* Returns the adapter position of the first {@link Preference} with the specified key.
*
* @param key Key of {@link Preference} to find
* @return Adapter position of the {@link Preference} or {@link RecyclerView#NO_POSITION}
* if not found
*/
int getPreferenceAdapterPosition(@NonNull String key);
/**
* Returns the adapter position of the specified {@link Preference} object
*
* @param preference {@link Preference} object to find
* @return Adapter position of the {@link Preference} or {@link RecyclerView#NO_POSITION}
* if not found
*/
int getPreferenceAdapterPosition(@NonNull Preference preference);
}
/**
* Definition for a callback to be invoked when the expand button is clicked.
*
* Used by Settings.
*
* @see #setInitialExpandedChildrenCount(int)
* @hide
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
public interface OnExpandButtonClickListener {
/**
* Called when the expand button is clicked.
*/
void onExpandButtonClick();
}
/**
* A class for managing the instance state of a {@link PreferenceGroup}.
*/
static class SavedState extends Preference.BaseSavedState {
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
int mInitialExpandedChildrenCount;
SavedState(Parcel source) {
super(source);
mInitialExpandedChildrenCount = source.readInt();
}
SavedState(Parcelable superState, int initialExpandedChildrenCount) {
super(superState);
mInitialExpandedChildrenCount = initialExpandedChildrenCount;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(mInitialExpandedChildrenCount);
}
}
}