blob: 238765702a1dc7bbe737993b758bde6b6eec0b75 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.preference;
18
Tor Norbyec615c6f2015-03-02 10:11:44 -080019import android.annotation.CallSuper;
Tor Norbye7b9c9122013-05-30 16:48:33 -070020import android.annotation.DrawableRes;
21import android.annotation.LayoutRes;
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +000022import android.annotation.Nullable;
Tor Norbye7b9c9122013-05-30 16:48:33 -070023import android.annotation.StringRes;
Mathew Inwoodeac8d0a2018-08-17 13:51:26 +010024import android.annotation.UnsupportedAppUsage;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import android.content.Context;
26import android.content.Intent;
27import android.content.SharedPreferences;
28import android.content.res.TypedArray;
Amith Yamasanib65897b2010-11-17 13:49:27 -080029import android.graphics.drawable.Drawable;
Mathew Inwood45d2c252018-09-14 12:35:36 +010030import android.os.Build;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.os.Bundle;
32import android.os.Parcel;
33import android.os.Parcelable;
34import android.text.TextUtils;
35import android.util.AttributeSet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.view.AbsSavedState;
John Reck014fea22011-06-15 16:46:36 -070037import android.view.KeyEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import android.view.LayoutInflater;
39import android.view.View;
40import android.view.ViewGroup;
Amith Yamasanib65897b2010-11-17 13:49:27 -080041import android.widget.ImageView;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.widget.ListView;
43import android.widget.TextView;
44
Fan Zhangc1caca12017-04-24 10:05:12 -070045import com.android.internal.util.CharSequences;
46
Adam Powell212db7d2010-04-08 16:24:46 -070047import java.util.ArrayList;
48import java.util.List;
49import java.util.Set;
50
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051/**
52 * Represents the basic Preference UI building
53 * block displayed by a {@link PreferenceActivity} in the form of a
54 * {@link ListView}. This class provides the {@link View} to be displayed in
55 * the activity and associates with a {@link SharedPreferences} to
56 * store/retrieve the preference data.
57 * <p>
58 * When specifying a preference hierarchy in XML, each element can point to a
59 * subclass of {@link Preference}, similar to the view hierarchy and layouts.
60 * <p>
61 * This class contains a {@code key} that will be used as the key into the
62 * {@link SharedPreferences}. It is up to the subclass to decide how to store
63 * the value.
Tony Mantler9a6b11b2016-09-13 15:53:35 -070064 *
Scott Maincdd0c592012-07-26 17:03:51 -070065 * <div class="special reference">
66 * <h3>Developer Guides</h3>
67 * <p>For information about building a settings UI with Preferences,
68 * read the <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a>
69 * guide.</p>
70 * </div>
Tony Mantler9a6b11b2016-09-13 15:53:35 -070071 *
Amith Yamasanib65897b2010-11-17 13:49:27 -080072 * @attr ref android.R.styleable#Preference_icon
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073 * @attr ref android.R.styleable#Preference_key
74 * @attr ref android.R.styleable#Preference_title
75 * @attr ref android.R.styleable#Preference_summary
76 * @attr ref android.R.styleable#Preference_order
Dianne Hackbornb3cf10f2010-08-03 13:07:11 -070077 * @attr ref android.R.styleable#Preference_fragment
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078 * @attr ref android.R.styleable#Preference_layout
79 * @attr ref android.R.styleable#Preference_widgetLayout
80 * @attr ref android.R.styleable#Preference_enabled
81 * @attr ref android.R.styleable#Preference_selectable
82 * @attr ref android.R.styleable#Preference_dependency
83 * @attr ref android.R.styleable#Preference_persistent
84 * @attr ref android.R.styleable#Preference_defaultValue
85 * @attr ref android.R.styleable#Preference_shouldDisableView
Filip Pavlis4186b342017-03-07 14:58:41 +000086 * @attr ref android.R.styleable#Preference_recycleEnabled
Doris Ling2cb4bab2017-03-20 13:33:45 -070087 * @attr ref android.R.styleable#Preference_singleLineTitle
Doris Ling9ed53e32017-03-27 13:32:04 -070088 * @attr ref android.R.styleable#Preference_iconSpaceReserved
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089 */
Alan Viverette02f56802013-08-19 16:32:56 -070090public class Preference implements Comparable<Preference> {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 /**
92 * Specify for {@link #setOrder(int)} if a specific order is not required.
93 */
94 public static final int DEFAULT_ORDER = Integer.MAX_VALUE;
95
96 private Context mContext;
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +000097
98 @Nullable
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099 private PreferenceManager mPreferenceManager;
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700100
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101 /**
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +0000102 * The data store that should be used by this Preference to store / retrieve data. If null then
103 * {@link PreferenceManager#getPreferenceDataStore()} needs to be checked. If that one is null
104 * too it means that we are using {@link android.content.SharedPreferences} to store the data.
105 */
106 @Nullable
107 private PreferenceDataStore mPreferenceDataStore;
108
109 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110 * Set when added to hierarchy since we need a unique ID within that
111 * hierarchy.
112 */
113 private long mId;
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115 private OnPreferenceChangeListener mOnChangeListener;
116 private OnPreferenceClickListener mOnClickListener;
117
118 private int mOrder = DEFAULT_ORDER;
119 private CharSequence mTitle;
Dianne Hackborne72f2372011-03-16 10:43:18 -0700120 private int mTitleRes;
Mathew Inwoodeac8d0a2018-08-17 13:51:26 +0100121 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122 private CharSequence mSummary;
Amith Yamasanib65897b2010-11-17 13:49:27 -0800123 /**
124 * mIconResId is overridden by mIcon, if mIcon is specified.
125 */
126 private int mIconResId;
127 private Drawable mIcon;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128 private String mKey;
129 private Intent mIntent;
Dianne Hackbornb3cf10f2010-08-03 13:07:11 -0700130 private String mFragment;
Dianne Hackborndef15372010-08-15 12:43:52 -0700131 private Bundle mExtras;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132 private boolean mEnabled = true;
133 private boolean mSelectable = true;
134 private boolean mRequiresKey;
135 private boolean mPersistent = true;
136 private String mDependencyKey;
137 private Object mDefaultValue;
Michael Chanda53eca2009-03-27 17:46:36 -0700138 private boolean mDependencyMet = true;
Alan Viverette02f56802013-08-19 16:32:56 -0700139 private boolean mParentDependencyMet = true;
Filip Pavlis4186b342017-03-07 14:58:41 +0000140 private boolean mRecycleEnabled = true;
Doris Lingce580462017-04-14 14:04:32 -0700141 private boolean mHasSingleLineTitleAttr;
Doris Ling2cb4bab2017-03-20 13:33:45 -0700142 private boolean mSingleLineTitle = true;
Doris Ling9ed53e32017-03-27 13:32:04 -0700143 private boolean mIconSpaceReserved;
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145 /**
146 * @see #setShouldDisableView(boolean)
147 */
148 private boolean mShouldDisableView = true;
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700149
Mathew Inwoodeac8d0a2018-08-17 13:51:26 +0100150 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 private int mLayoutResId = com.android.internal.R.layout.preference;
Mathew Inwoodeac8d0a2018-08-17 13:51:26 +0100152 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 private int mWidgetLayoutResId;
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 private OnPreferenceChangeInternalListener mListener;
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700156
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 private List<Preference> mDependents;
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700158
Filip Pavliscba64582017-01-10 19:17:09 +0000159 private PreferenceGroup mParentGroup;
160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 private boolean mBaseMethodCalled;
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700162
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 /**
164 * Interface definition for a callback to be invoked when the value of this
165 * {@link Preference} has been changed by the user and is
166 * about to be set and/or persisted. This gives the client a chance
167 * to prevent setting and/or persisting the value.
168 */
169 public interface OnPreferenceChangeListener {
170 /**
171 * Called when a Preference has been changed by the user. This is
172 * called before the state of the Preference is about to be updated and
173 * before the state is persisted.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700174 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175 * @param preference The changed Preference.
176 * @param newValue The new value of the Preference.
177 * @return True to update the state of the Preference with the new value.
178 */
179 boolean onPreferenceChange(Preference preference, Object newValue);
180 }
181
182 /**
183 * Interface definition for a callback to be invoked when a {@link Preference} is
184 * clicked.
185 */
186 public interface OnPreferenceClickListener {
187 /**
188 * Called when a Preference has been clicked.
189 *
190 * @param preference The Preference that was clicked.
191 * @return True if the click was handled.
192 */
193 boolean onPreferenceClick(Preference preference);
194 }
195
196 /**
197 * Interface definition for a callback to be invoked when this
198 * {@link Preference} is changed or, if this is a group, there is an
199 * addition/removal of {@link Preference}(s). This is used internally.
200 */
201 interface OnPreferenceChangeInternalListener {
202 /**
203 * Called when this Preference has changed.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700204 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 * @param preference This preference.
206 */
207 void onPreferenceChange(Preference preference);
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 /**
210 * Called when this group has added/removed {@link Preference}(s).
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700211 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 * @param preference This Preference.
213 */
214 void onPreferenceHierarchyChange(Preference preference);
215 }
216
217 /**
218 * Perform inflation from XML and apply a class-specific base style. This
Alan Viverette617feb92013-09-09 18:09:13 -0700219 * constructor of Preference allows subclasses to use their own base style
220 * when they are inflating. For example, a {@link CheckBoxPreference}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 * constructor calls this version of the super class constructor and
Alan Viverette617feb92013-09-09 18:09:13 -0700222 * supplies {@code android.R.attr.checkBoxPreferenceStyle} for
223 * <var>defStyleAttr</var>. This allows the theme's checkbox preference
224 * style to modify all of the base preference attributes as well as the
225 * {@link CheckBoxPreference} class's attributes.
226 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227 * @param context The Context this is associated with, through which it can
Alan Viverette617feb92013-09-09 18:09:13 -0700228 * access the current theme, resources,
229 * {@link SharedPreferences}, etc.
230 * @param attrs The attributes of the XML tag that is inflating the
231 * preference.
232 * @param defStyleAttr An attribute in the current theme that contains a
233 * reference to a style resource that supplies default values for
234 * the view. Can be 0 to not look for defaults.
235 * @param defStyleRes A resource identifier of a style resource that
236 * supplies default values for the view, used only if
237 * defStyleAttr is 0 or can not be found in the theme. Can be 0
238 * to not look for defaults.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239 * @see #Preference(Context, AttributeSet)
240 */
Alan Viverette617feb92013-09-09 18:09:13 -0700241 public Preference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 mContext = context;
243
Alan Viverette617feb92013-09-09 18:09:13 -0700244 final TypedArray a = context.obtainStyledAttributes(
245 attrs, com.android.internal.R.styleable.Preference, defStyleAttr, defStyleRes);
Deepanshu Gupta10bb1372014-10-05 14:41:17 -0700246 for (int i = a.getIndexCount() - 1; i >= 0; i--) {
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700247 int attr = a.getIndex(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248 switch (attr) {
Amith Yamasanib65897b2010-11-17 13:49:27 -0800249 case com.android.internal.R.styleable.Preference_icon:
250 mIconResId = a.getResourceId(attr, 0);
251 break;
252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 case com.android.internal.R.styleable.Preference_key:
254 mKey = a.getString(attr);
255 break;
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700256
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800257 case com.android.internal.R.styleable.Preference_title:
Dianne Hackborne72f2372011-03-16 10:43:18 -0700258 mTitleRes = a.getResourceId(attr, 0);
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700259 mTitle = a.getText(attr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260 break;
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700261
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800262 case com.android.internal.R.styleable.Preference_summary:
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700263 mSummary = a.getText(attr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 break;
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700265
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 case com.android.internal.R.styleable.Preference_order:
267 mOrder = a.getInt(attr, mOrder);
268 break;
269
Dianne Hackbornb3cf10f2010-08-03 13:07:11 -0700270 case com.android.internal.R.styleable.Preference_fragment:
271 mFragment = a.getString(attr);
272 break;
273
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274 case com.android.internal.R.styleable.Preference_layout:
275 mLayoutResId = a.getResourceId(attr, mLayoutResId);
276 break;
277
278 case com.android.internal.R.styleable.Preference_widgetLayout:
279 mWidgetLayoutResId = a.getResourceId(attr, mWidgetLayoutResId);
280 break;
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800282 case com.android.internal.R.styleable.Preference_enabled:
283 mEnabled = a.getBoolean(attr, true);
284 break;
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286 case com.android.internal.R.styleable.Preference_selectable:
287 mSelectable = a.getBoolean(attr, true);
288 break;
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800290 case com.android.internal.R.styleable.Preference_persistent:
291 mPersistent = a.getBoolean(attr, mPersistent);
292 break;
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294 case com.android.internal.R.styleable.Preference_dependency:
295 mDependencyKey = a.getString(attr);
296 break;
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800298 case com.android.internal.R.styleable.Preference_defaultValue:
299 mDefaultValue = onGetDefaultValue(a, attr);
300 break;
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800302 case com.android.internal.R.styleable.Preference_shouldDisableView:
303 mShouldDisableView = a.getBoolean(attr, mShouldDisableView);
304 break;
Filip Pavlis4186b342017-03-07 14:58:41 +0000305
306 case com.android.internal.R.styleable.Preference_recycleEnabled:
307 mRecycleEnabled = a.getBoolean(attr, mRecycleEnabled);
308 break;
Doris Ling2cb4bab2017-03-20 13:33:45 -0700309
310 case com.android.internal.R.styleable.Preference_singleLineTitle:
311 mSingleLineTitle = a.getBoolean(attr, mSingleLineTitle);
Doris Lingce580462017-04-14 14:04:32 -0700312 mHasSingleLineTitleAttr = true;
Doris Ling2cb4bab2017-03-20 13:33:45 -0700313 break;
Doris Ling9ed53e32017-03-27 13:32:04 -0700314
315 case com.android.internal.R.styleable.Preference_iconSpaceReserved:
316 mIconSpaceReserved = a.getBoolean(attr, mIconSpaceReserved);
317 break;
318 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 }
320 a.recycle();
321 }
Alan Viverette617feb92013-09-09 18:09:13 -0700322
323 /**
324 * Perform inflation from XML and apply a class-specific base style. This
325 * constructor of Preference allows subclasses to use their own base style
326 * when they are inflating. For example, a {@link CheckBoxPreference}
327 * constructor calls this version of the super class constructor and
328 * supplies {@code android.R.attr.checkBoxPreferenceStyle} for
329 * <var>defStyleAttr</var>. This allows the theme's checkbox preference
330 * style to modify all of the base preference attributes as well as the
331 * {@link CheckBoxPreference} class's attributes.
332 *
333 * @param context The Context this is associated with, through which it can
334 * access the current theme, resources,
335 * {@link SharedPreferences}, etc.
336 * @param attrs The attributes of the XML tag that is inflating the
337 * preference.
338 * @param defStyleAttr An attribute in the current theme that contains a
339 * reference to a style resource that supplies default values for
340 * the view. Can be 0 to not look for defaults.
341 * @see #Preference(Context, AttributeSet)
342 */
343 public Preference(Context context, AttributeSet attrs, int defStyleAttr) {
344 this(context, attrs, defStyleAttr, 0);
345 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700346
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347 /**
348 * Constructor that is called when inflating a Preference from XML. This is
349 * called when a Preference is being constructed from an XML file, supplying
350 * attributes that were specified in the XML file. This version uses a
351 * default style of 0, so the only attribute values applied are those in the
352 * Context's Theme and the given AttributeSet.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700353 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354 * @param context The Context this is associated with, through which it can
355 * access the current theme, resources, {@link SharedPreferences},
356 * etc.
357 * @param attrs The attributes of the XML tag that is inflating the
358 * preference.
359 * @see #Preference(Context, AttributeSet, int)
360 */
361 public Preference(Context context, AttributeSet attrs) {
Amith Yamasanie4946622011-01-16 16:12:51 -0800362 this(context, attrs, com.android.internal.R.attr.preferenceStyle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 }
364
365 /**
366 * Constructor to create a Preference.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700367 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368 * @param context The Context in which to store Preference values.
369 */
370 public Preference(Context context) {
371 this(context, null);
372 }
373
374 /**
375 * Called when a Preference is being inflated and the default value
376 * attribute needs to be read. Since different Preference types have
377 * different value types, the subclass should get and return the default
378 * value which will be its value type.
379 * <p>
380 * For example, if the value type is String, the body of the method would
381 * proxy to {@link TypedArray#getString(int)}.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700382 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800383 * @param a The set of attributes.
384 * @param index The index of the default value attribute.
385 * @return The default value of this preference type.
386 */
387 protected Object onGetDefaultValue(TypedArray a, int index) {
388 return null;
389 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700390
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800391 /**
392 * Sets an {@link Intent} to be used for
393 * {@link Context#startActivity(Intent)} when this Preference is clicked.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700394 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 * @param intent The intent associated with this Preference.
396 */
397 public void setIntent(Intent intent) {
398 mIntent = intent;
399 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700400
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401 /**
402 * Return the {@link Intent} associated with this Preference.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700403 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 * @return The {@link Intent} last set via {@link #setIntent(Intent)} or XML.
405 */
406 public Intent getIntent() {
407 return mIntent;
408 }
409
410 /**
Dianne Hackbornb3cf10f2010-08-03 13:07:11 -0700411 * Sets the class name of a fragment to be shown when this Preference is clicked.
412 *
413 * @param fragment The class name of the fragment associated with this Preference.
414 */
415 public void setFragment(String fragment) {
416 mFragment = fragment;
417 }
418
419 /**
420 * Return the fragment class name associated with this Preference.
421 *
422 * @return The fragment class name last set via {@link #setFragment} or XML.
423 */
424 public String getFragment() {
425 return mFragment;
426 }
427
428 /**
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +0000429 * Sets a {@link PreferenceDataStore} to be used by this Preference instead of using
430 * {@link android.content.SharedPreferences}.
Filip Pavlisfd596452017-03-01 18:50:00 +0000431 *
432 * <p>The data store will remain assigned even if the Preference is moved around the preference
433 * hierarchy. It will also override a data store propagated from the {@link PreferenceManager}
434 * that owns this Preference.
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +0000435 *
436 * @param dataStore The {@link PreferenceDataStore} to be used by this Preference.
Filip Pavlisfd596452017-03-01 18:50:00 +0000437 * @see PreferenceManager#setPreferenceDataStore(PreferenceDataStore)
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +0000438 */
439 public void setPreferenceDataStore(PreferenceDataStore dataStore) {
440 mPreferenceDataStore = dataStore;
441 }
442
443 /**
444 * Returns {@link PreferenceDataStore} used by this Preference. Returns {@code null} if
445 * {@link android.content.SharedPreferences} is used instead.
446 *
Filip Pavlisfd596452017-03-01 18:50:00 +0000447 * <p>By default preferences always use {@link android.content.SharedPreferences}. To make this
448 * preference to use the {@link PreferenceDataStore} you need to assign your implementation
449 * to the Preference itself via {@link #setPreferenceDataStore(PreferenceDataStore)} or to its
450 * {@link PreferenceManager} via
451 * {@link PreferenceManager#setPreferenceDataStore(PreferenceDataStore)}.
452 *
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +0000453 * @return The {@link PreferenceDataStore} used by this Preference or {@code null} if none.
454 */
455 @Nullable
456 public PreferenceDataStore getPreferenceDataStore() {
457 if (mPreferenceDataStore != null) {
458 return mPreferenceDataStore;
459 } else if (mPreferenceManager != null) {
460 return mPreferenceManager.getPreferenceDataStore();
461 }
462
463 return null;
464 }
465
466 /**
Dianne Hackborndef15372010-08-15 12:43:52 -0700467 * Return the extras Bundle object associated with this preference, creating
468 * a new Bundle if there currently isn't one. You can use this to get and
469 * set individual extra key/value pairs.
470 */
471 public Bundle getExtras() {
472 if (mExtras == null) {
473 mExtras = new Bundle();
474 }
475 return mExtras;
476 }
477
478 /**
Filip Pavlisee3bc342017-03-13 16:58:24 +0000479 * Return the extras Bundle object associated with this preference, returning {@code null} if
480 * there is not currently one.
Dianne Hackborndef15372010-08-15 12:43:52 -0700481 */
482 public Bundle peekExtras() {
483 return mExtras;
484 }
485
486 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800487 * Sets the layout resource that is inflated as the {@link View} to be shown
488 * for this Preference. In most cases, the default layout is sufficient for
489 * custom Preference objects and only the widget layout needs to be changed.
490 * <p>
491 * This layout should contain a {@link ViewGroup} with ID
492 * {@link android.R.id#widget_frame} to be the parent of the specific widget
493 * for this Preference. It should similarly contain
494 * {@link android.R.id#title} and {@link android.R.id#summary}.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700495 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800496 * @param layoutResId The layout resource ID to be inflated and returned as
497 * a {@link View}.
498 * @see #setWidgetLayoutResource(int)
499 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700500 public void setLayoutResource(@LayoutRes int layoutResId) {
Amith Yamasania98129b2009-10-05 15:31:47 -0700501 if (layoutResId != mLayoutResId) {
502 // Layout changed
Filip Pavlis4186b342017-03-07 14:58:41 +0000503 mRecycleEnabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504 }
Amith Yamasania98129b2009-10-05 15:31:47 -0700505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 mLayoutResId = layoutResId;
507 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 /**
510 * Gets the layout resource that will be shown as the {@link View} for this Preference.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700511 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512 * @return The layout resource ID.
513 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700514 @LayoutRes
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800515 public int getLayoutResource() {
516 return mLayoutResId;
517 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800519 /**
Alan Viverette791b37e2013-08-20 17:34:19 -0700520 * Sets the layout for the controllable widget portion of this Preference. This
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800521 * is inflated into the main layout. For example, a {@link CheckBoxPreference}
522 * would specify a custom layout (consisting of just the CheckBox) here,
523 * instead of creating its own main layout.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700524 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800525 * @param widgetLayoutResId The layout resource ID to be inflated into the
526 * main layout.
527 * @see #setLayoutResource(int)
528 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700529 public void setWidgetLayoutResource(@LayoutRes int widgetLayoutResId) {
Amith Yamasania98129b2009-10-05 15:31:47 -0700530 if (widgetLayoutResId != mWidgetLayoutResId) {
531 // Layout changed
Filip Pavlis4186b342017-03-07 14:58:41 +0000532 mRecycleEnabled = false;
Amith Yamasania98129b2009-10-05 15:31:47 -0700533 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534 mWidgetLayoutResId = widgetLayoutResId;
535 }
536
537 /**
538 * Gets the layout resource for the controllable widget portion of this Preference.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700539 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800540 * @return The layout resource ID.
541 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700542 @LayoutRes
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800543 public int getWidgetLayoutResource() {
544 return mWidgetLayoutResId;
545 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700546
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800547 /**
548 * Gets the View that will be shown in the {@link PreferenceActivity}.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700549 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 * @param convertView The old View to reuse, if possible. Note: You should
551 * check that this View is non-null and of an appropriate type
552 * before using. If it is not possible to convert this View to
553 * display the correct data, this method can create a new View.
554 * @param parent The parent that this View will eventually be attached to.
555 * @return Returns the same Preference object, for chaining multiple calls
556 * into a single statement.
557 * @see #onCreateView(ViewGroup)
558 * @see #onBindView(View)
559 */
560 public View getView(View convertView, ViewGroup parent) {
561 if (convertView == null) {
Amith Yamasanibae6fc22009-09-30 14:08:07 -0700562 convertView = onCreateView(parent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800563 }
564 onBindView(convertView);
565 return convertView;
566 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800568 /**
569 * Creates the View to be shown for this Preference in the
570 * {@link PreferenceActivity}. The default behavior is to inflate the main
571 * layout of this Preference (see {@link #setLayoutResource(int)}. If
572 * changing this behavior, please specify a {@link ViewGroup} with ID
573 * {@link android.R.id#widget_frame}.
574 * <p>
575 * Make sure to call through to the superclass's implementation.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700576 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800577 * @param parent The parent that this View will eventually be attached to.
578 * @return The View that displays this Preference.
579 * @see #onBindView(View)
580 */
Tor Norbyec615c6f2015-03-02 10:11:44 -0800581 @CallSuper
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800582 protected View onCreateView(ViewGroup parent) {
583 final LayoutInflater layoutInflater =
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700584 (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
585
586 final View layout = layoutInflater.inflate(mLayoutResId, parent, false);
587
Amith Yamasani405c1af2011-05-26 13:08:25 -0700588 final ViewGroup widgetFrame = (ViewGroup) layout
589 .findViewById(com.android.internal.R.id.widget_frame);
590 if (widgetFrame != null) {
591 if (mWidgetLayoutResId != 0) {
592 layoutInflater.inflate(mWidgetLayoutResId, widgetFrame);
593 } else {
594 widgetFrame.setVisibility(View.GONE);
595 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800596 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597 return layout;
598 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700599
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800600 /**
601 * Binds the created View to the data for this Preference.
602 * <p>
603 * This is a good place to grab references to custom Views in the layout and
604 * set properties on them.
605 * <p>
606 * Make sure to call through to the superclass's implementation.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700607 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800608 * @param view The View that shows this Preference.
609 * @see #onCreateView(ViewGroup)
610 */
Tor Norbyec615c6f2015-03-02 10:11:44 -0800611 @CallSuper
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800612 protected void onBindView(View view) {
Alan Viverette55565ec2014-04-09 16:52:54 -0700613 final TextView titleView = (TextView) view.findViewById(com.android.internal.R.id.title);
Jeff Sharkey0f1c3af2012-04-03 20:46:42 -0700614 if (titleView != null) {
615 final CharSequence title = getTitle();
616 if (!TextUtils.isEmpty(title)) {
617 titleView.setText(title);
618 titleView.setVisibility(View.VISIBLE);
Doris Lingce580462017-04-14 14:04:32 -0700619 if (mHasSingleLineTitleAttr) {
620 titleView.setSingleLine(mSingleLineTitle);
621 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800622 } else {
Jeff Sharkey0f1c3af2012-04-03 20:46:42 -0700623 titleView.setVisibility(View.GONE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800624 }
625 }
Jeff Sharkey0f1c3af2012-04-03 20:46:42 -0700626
627 final TextView summaryView = (TextView) view.findViewById(
628 com.android.internal.R.id.summary);
629 if (summaryView != null) {
630 final CharSequence summary = getSummary();
631 if (!TextUtils.isEmpty(summary)) {
632 summaryView.setText(summary);
633 summaryView.setVisibility(View.VISIBLE);
634 } else {
635 summaryView.setVisibility(View.GONE);
636 }
637 }
638
Alan Viverette55565ec2014-04-09 16:52:54 -0700639 final ImageView imageView = (ImageView) view.findViewById(com.android.internal.R.id.icon);
Amith Yamasani405c1af2011-05-26 13:08:25 -0700640 if (imageView != null) {
641 if (mIconResId != 0 || mIcon != null) {
642 if (mIcon == null) {
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800643 mIcon = getContext().getDrawable(mIconResId);
Amith Yamasani405c1af2011-05-26 13:08:25 -0700644 }
645 if (mIcon != null) {
646 imageView.setImageDrawable(mIcon);
647 }
Amith Yamasanib65897b2010-11-17 13:49:27 -0800648 }
Doris Ling9ed53e32017-03-27 13:32:04 -0700649 if (mIcon != null) {
650 imageView.setVisibility(View.VISIBLE);
651 } else {
652 imageView.setVisibility(mIconSpaceReserved ? View.INVISIBLE : View.GONE);
653 }
Amith Yamasanib65897b2010-11-17 13:49:27 -0800654 }
Amith Yamasani405c1af2011-05-26 13:08:25 -0700655
Alan Viverette55565ec2014-04-09 16:52:54 -0700656 final View imageFrame = view.findViewById(com.android.internal.R.id.icon_frame);
657 if (imageFrame != null) {
Fan Zhangc1caca12017-04-24 10:05:12 -0700658 if (mIcon != null) {
659 imageFrame.setVisibility(View.VISIBLE);
660 } else {
661 imageFrame.setVisibility(mIconSpaceReserved ? View.INVISIBLE : View.GONE);
662 }
Alan Viverette55565ec2014-04-09 16:52:54 -0700663 }
664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665 if (mShouldDisableView) {
666 setEnabledStateOnViews(view, isEnabled());
667 }
668 }
Amith Yamasanib65897b2010-11-17 13:49:27 -0800669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800670 /**
671 * Makes sure the view (and any children) get the enabled state changed.
672 */
673 private void setEnabledStateOnViews(View v, boolean enabled) {
674 v.setEnabled(enabled);
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700675
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800676 if (v instanceof ViewGroup) {
677 final ViewGroup vg = (ViewGroup) v;
678 for (int i = vg.getChildCount() - 1; i >= 0; i--) {
679 setEnabledStateOnViews(vg.getChildAt(i), enabled);
680 }
681 }
682 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700683
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800684 /**
Filip Pavlis4186b342017-03-07 14:58:41 +0000685 * Sets the order of this Preference with respect to other Preference objects on the same level.
686 * If this is not specified, the default behavior is to sort alphabetically. The
687 * {@link PreferenceGroup#setOrderingAsAdded(boolean)} can be used to order Preference objects
688 * based on the order they appear in the XML.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700689 *
Filip Pavlis4186b342017-03-07 14:58:41 +0000690 * @param order the order for this Preference. A lower value will be shown first. Use
691 * {@link #DEFAULT_ORDER} to sort alphabetically or allow ordering from XML
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800692 * @see PreferenceGroup#setOrderingAsAdded(boolean)
693 * @see #DEFAULT_ORDER
694 */
695 public void setOrder(int order) {
696 if (order != mOrder) {
697 mOrder = order;
698
Filip Pavlis4186b342017-03-07 14:58:41 +0000699 // Reorder the list
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800700 notifyHierarchyChanged();
701 }
702 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700703
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704 /**
Filip Pavlis4186b342017-03-07 14:58:41 +0000705 * Gets the order of this Preference with respect to other Preference objects on the same level.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700706 *
Filip Pavlis4186b342017-03-07 14:58:41 +0000707 * @return the order of this Preference
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800708 * @see #setOrder(int)
709 */
710 public int getOrder() {
711 return mOrder;
712 }
713
714 /**
Filip Pavlis4186b342017-03-07 14:58:41 +0000715 * Sets the title for this Preference with a CharSequence. This title will be placed into the ID
716 * {@link android.R.id#title} within the View created by {@link #onCreateView(ViewGroup)}.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700717 *
Filip Pavlis4186b342017-03-07 14:58:41 +0000718 * @param title the title for this Preference
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800719 */
720 public void setTitle(CharSequence title) {
721 if (title == null && mTitle != null || title != null && !title.equals(mTitle)) {
Dianne Hackborne72f2372011-03-16 10:43:18 -0700722 mTitleRes = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723 mTitle = title;
724 notifyChanged();
725 }
726 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700727
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800728 /**
Filip Pavlis4186b342017-03-07 14:58:41 +0000729 * Sets the title for this Preference with a resource ID.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700730 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800731 * @see #setTitle(CharSequence)
Filip Pavlis4186b342017-03-07 14:58:41 +0000732 * @param titleResId the title as a resource ID
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800733 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700734 public void setTitle(@StringRes int titleResId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800735 setTitle(mContext.getString(titleResId));
Dianne Hackborne72f2372011-03-16 10:43:18 -0700736 mTitleRes = titleResId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800737 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700738
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800739 /**
Filip Pavlis4186b342017-03-07 14:58:41 +0000740 * Returns the title resource ID of this Preference. If the title did not come from a resource,
741 * {@code 0} is returned.
Dianne Hackborne72f2372011-03-16 10:43:18 -0700742 *
Filip Pavlis4186b342017-03-07 14:58:41 +0000743 * @return the title resource
Dianne Hackborne72f2372011-03-16 10:43:18 -0700744 * @see #setTitle(int)
745 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700746 @StringRes
Dianne Hackborne72f2372011-03-16 10:43:18 -0700747 public int getTitleRes() {
748 return mTitleRes;
749 }
750
751 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800752 * Returns the title of this Preference.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700753 *
Filip Pavlis4186b342017-03-07 14:58:41 +0000754 * @return the title
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800755 * @see #setTitle(CharSequence)
756 */
757 public CharSequence getTitle() {
758 return mTitle;
759 }
760
761 /**
Filip Pavlis4186b342017-03-07 14:58:41 +0000762 * Sets the icon for this Preference with a Drawable. This icon will be placed into the ID
763 * {@link android.R.id#icon} within the View created by {@link #onCreateView(ViewGroup)}.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700764 *
Filip Pavlis4186b342017-03-07 14:58:41 +0000765 * @param icon the optional icon for this Preference
Amith Yamasanib65897b2010-11-17 13:49:27 -0800766 */
767 public void setIcon(Drawable icon) {
768 if ((icon == null && mIcon != null) || (icon != null && mIcon != icon)) {
769 mIcon = icon;
Amith Yamasani405c1af2011-05-26 13:08:25 -0700770
Amith Yamasanib65897b2010-11-17 13:49:27 -0800771 notifyChanged();
772 }
773 }
774
775 /**
Filip Pavlis4186b342017-03-07 14:58:41 +0000776 * Sets the icon for this Preference with a resource ID.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700777 *
Amith Yamasanib65897b2010-11-17 13:49:27 -0800778 * @see #setIcon(Drawable)
Filip Pavlis4186b342017-03-07 14:58:41 +0000779 * @param iconResId the icon as a resource ID
Amith Yamasanib65897b2010-11-17 13:49:27 -0800780 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700781 public void setIcon(@DrawableRes int iconResId) {
Svet Ganov3695b8a2015-03-24 16:30:25 -0700782 if (mIconResId != iconResId) {
783 mIconResId = iconResId;
784 setIcon(mContext.getDrawable(iconResId));
785 }
Amith Yamasanib65897b2010-11-17 13:49:27 -0800786 }
787
788 /**
789 * Returns the icon of this Preference.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700790 *
Filip Pavlis4186b342017-03-07 14:58:41 +0000791 * @return the icon
Amith Yamasanib65897b2010-11-17 13:49:27 -0800792 * @see #setIcon(Drawable)
793 */
794 public Drawable getIcon() {
Michael Kwanf049e242016-09-07 13:15:55 -0700795 if (mIcon == null && mIconResId != 0) {
796 mIcon = getContext().getDrawable(mIconResId);
797 }
Amith Yamasanib65897b2010-11-17 13:49:27 -0800798 return mIcon;
799 }
800
801 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800802 * Returns the summary of this Preference.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700803 *
Filip Pavlis4186b342017-03-07 14:58:41 +0000804 * @return the summary
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800805 * @see #setSummary(CharSequence)
806 */
807 public CharSequence getSummary() {
808 return mSummary;
809 }
810
811 /**
Filip Pavlis4186b342017-03-07 14:58:41 +0000812 * Sets the summary for this Preference with a CharSequence.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700813 *
Filip Pavlis4186b342017-03-07 14:58:41 +0000814 * @param summary the summary for the preference
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800815 */
816 public void setSummary(CharSequence summary) {
817 if (summary == null && mSummary != null || summary != null && !summary.equals(mSummary)) {
818 mSummary = summary;
819 notifyChanged();
820 }
821 }
822
823 /**
Filip Pavlis4186b342017-03-07 14:58:41 +0000824 * Sets the summary for this Preference with a resource ID.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700825 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800826 * @see #setSummary(CharSequence)
Filip Pavlis4186b342017-03-07 14:58:41 +0000827 * @param summaryResId the summary as a resource
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800828 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700829 public void setSummary(@StringRes int summaryResId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 setSummary(mContext.getString(summaryResId));
831 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700832
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800833 /**
834 * Sets whether this Preference is enabled. If disabled, it will
835 * not handle clicks.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700836 *
Filip Pavlis4186b342017-03-07 14:58:41 +0000837 * @param enabled set {@code true} to enable it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800838 */
839 public void setEnabled(boolean enabled) {
840 if (mEnabled != enabled) {
841 mEnabled = enabled;
842
843 // Enabled state can change dependent preferences' states, so notify
844 notifyDependencyChange(shouldDisableDependents());
845
846 notifyChanged();
847 }
848 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700849
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850 /**
851 * Checks whether this Preference should be enabled in the list.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700852 *
Filip Pavlis4186b342017-03-07 14:58:41 +0000853 * @return {@code true} if this Preference is enabled, false otherwise
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800854 */
855 public boolean isEnabled() {
Alan Viverette02f56802013-08-19 16:32:56 -0700856 return mEnabled && mDependencyMet && mParentDependencyMet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800857 }
858
859 /**
860 * Sets whether this Preference is selectable.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700861 *
Filip Pavlis4186b342017-03-07 14:58:41 +0000862 * @param selectable set {@code true} to make it selectable
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800863 */
864 public void setSelectable(boolean selectable) {
865 if (mSelectable != selectable) {
866 mSelectable = selectable;
867 notifyChanged();
868 }
869 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700870
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800871 /**
872 * Checks whether this Preference should be selectable in the list.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700873 *
Filip Pavlis4186b342017-03-07 14:58:41 +0000874 * @return {@code true} if it is selectable, {@code false} otherwise
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800875 */
876 public boolean isSelectable() {
877 return mSelectable;
878 }
879
880 /**
Filip Pavlis4186b342017-03-07 14:58:41 +0000881 * Sets whether this Preference should disable its view when it gets disabled.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700882 *
Filip Pavlis4186b342017-03-07 14:58:41 +0000883 * <p>For example, set this and {@link #setEnabled(boolean)} to false for preferences that are
884 * only displaying information and 1) should not be clickable 2) should not have the view set to
885 * the disabled state.
886 *
887 * @param shouldDisableView set {@code true} if this preference should disable its view when
888 * the preference is disabled
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800889 */
890 public void setShouldDisableView(boolean shouldDisableView) {
891 mShouldDisableView = shouldDisableView;
892 notifyChanged();
893 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700894
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800895 /**
896 * Checks whether this Preference should disable its view when it's action is disabled.
Filip Pavlis4186b342017-03-07 14:58:41 +0000897 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800898 * @see #setShouldDisableView(boolean)
Filip Pavlis4186b342017-03-07 14:58:41 +0000899 * @return {@code true} if it should disable the view
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800900 */
901 public boolean getShouldDisableView() {
902 return mShouldDisableView;
903 }
904
905 /**
Filip Pavlis4186b342017-03-07 14:58:41 +0000906 * Sets whether this Preference has enabled to have its view recycled when used in the list
907 * view. By default the recycling is enabled.
908 *
909 * <p>The value can be changed only before this preference is added to the preference hierarchy.
910 *
911 * <p>If view recycling is not allowed then each time the list view populates this preference
912 * the {@link #getView(View, ViewGroup)} method receives a {@code null} convert view and needs
913 * to recreate the view. Otherwise view gets recycled and only {@link #onBindView(View)} gets
914 * called.
915 *
916 * @param enabled set {@code true} if this preference view should be recycled
917 */
918 @CallSuper
919 public void setRecycleEnabled(boolean enabled) {
920 mRecycleEnabled = enabled;
921 notifyChanged();
922 }
923
924 /**
925 * Checks whether this Preference has enabled to have its view recycled when used in the list
926 * view.
927 *
928 * @see #setRecycleEnabled(boolean)
929 * @return {@code true} if this preference view should be recycled
930 */
931 public boolean isRecycleEnabled() {
932 return mRecycleEnabled;
933 }
934
935 /**
Doris Ling2cb4bab2017-03-20 13:33:45 -0700936 * Sets whether to constrain the title of this Preference to a single line instead of
937 * letting it wrap onto multiple lines.
938 *
939 * @param singleLineTitle set {@code true} if the title should be constrained to one line
940 */
941 public void setSingleLineTitle(boolean singleLineTitle) {
Doris Ling846234f2017-06-23 13:41:22 -0700942 mHasSingleLineTitleAttr = true;
Doris Ling2cb4bab2017-03-20 13:33:45 -0700943 mSingleLineTitle = singleLineTitle;
944 notifyChanged();
945 }
946
947 /**
948 * Gets whether the title of this preference is constrained to a single line.
949 *
950 * @see #setSingleLineTitle(boolean)
951 * @return {@code true} if the title of this preference is constrained to a single line
952 */
953 public boolean isSingleLineTitle() {
954 return mSingleLineTitle;
955 }
956
957 /**
Doris Ling9ed53e32017-03-27 13:32:04 -0700958 * Sets whether to reserve the space of this Preference icon view when no icon is provided.
959 *
960 * @param iconSpaceReserved set {@code true} if the space for the icon view should be reserved
961 */
962 public void setIconSpaceReserved(boolean iconSpaceReserved) {
963 mIconSpaceReserved = iconSpaceReserved;
964 notifyChanged();
965 }
966
967 /**
968 * Gets whether the space this preference icon view is reserved.
969 *
970 * @see #setIconSpaceReserved(boolean)
971 * @return {@code true} if the space of this preference icon view is reserved
972 */
973 public boolean isIconSpaceReserved() {
974 return mIconSpaceReserved;
975 }
976 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800977 * Returns a unique ID for this Preference. This ID should be unique across all
978 * Preference objects in a hierarchy.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700979 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800980 * @return A unique ID for this Preference.
981 */
Mathew Inwoodeac8d0a2018-08-17 13:51:26 +0100982 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800983 long getId() {
984 return mId;
985 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700986
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800987 /**
988 * Processes a click on the preference. This includes saving the value to
989 * the {@link SharedPreferences}. However, the overridden method should
990 * call {@link #callChangeListener(Object)} to make sure the client wants to
991 * update the preference's state with the new value.
992 */
993 protected void onClick() {
994 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700995
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800996 /**
Filip Pavlis09557932017-03-03 16:54:22 +0000997 * Sets the key for this Preference, which is used as a key to the {@link SharedPreferences} or
998 * {@link PreferenceDataStore}. This should be unique for the package.
Tony Mantler9a6b11b2016-09-13 15:53:35 -0700999 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000 * @param key The key for the preference.
1001 */
1002 public void setKey(String key) {
1003 mKey = key;
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001004
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001005 if (mRequiresKey && !hasKey()) {
1006 requireKey();
1007 }
1008 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001009
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001010 /**
Filip Pavlis09557932017-03-03 16:54:22 +00001011 * Gets the key for this Preference, which is also the key used for storing values into
1012 * {@link SharedPreferences} or {@link PreferenceDataStore}.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001013 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001014 * @return The key.
1015 */
1016 public String getKey() {
1017 return mKey;
1018 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001019
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001020 /**
1021 * Checks whether the key is present, and if it isn't throws an
Filip Pavlis09557932017-03-03 16:54:22 +00001022 * exception. This should be called by subclasses that persist their preferences.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001023 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001024 * @throws IllegalStateException If there is no key assigned.
1025 */
1026 void requireKey() {
1027 if (mKey == null) {
1028 throw new IllegalStateException("Preference does not have a key assigned.");
1029 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001030
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001031 mRequiresKey = true;
1032 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001033
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001034 /**
1035 * Checks whether this Preference has a valid key.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001036 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001037 * @return True if the key exists and is not a blank string, false otherwise.
1038 */
1039 public boolean hasKey() {
1040 return !TextUtils.isEmpty(mKey);
1041 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001042
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001043 /**
1044 * Checks whether this Preference is persistent. If it is, it stores its value(s) into
Filip Pavlis09557932017-03-03 16:54:22 +00001045 * the persistent {@link SharedPreferences} storage by default or into
1046 * {@link PreferenceDataStore} if assigned.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001047 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001048 * @return True if it is persistent.
1049 */
1050 public boolean isPersistent() {
1051 return mPersistent;
1052 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001053
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001054 /**
Filip Pavlis09557932017-03-03 16:54:22 +00001055 * Checks whether, at the given time this method is called, this Preference should store/restore
1056 * its value(s) into the {@link SharedPreferences} or into {@link PreferenceDataStore} if
1057 * assigned. This, at minimum, checks whether this Preference is persistent and it currently has
1058 * a key. Before you save/restore from the storage, check this first.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001059 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001060 * @return True if it should persist the value.
1061 */
1062 protected boolean shouldPersist() {
1063 return mPreferenceManager != null && isPersistent() && hasKey();
1064 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001065
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001066 /**
Filip Pavlis09557932017-03-03 16:54:22 +00001067 * Sets whether this Preference is persistent. When persistent, it stores its value(s) into
1068 * the persistent {@link SharedPreferences} storage by default or into
1069 * {@link PreferenceDataStore} if assigned.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001070 *
Filip Pavlisee3bc342017-03-13 16:58:24 +00001071 * @param persistent set {@code true} if it should store its value(s) into the storage.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001072 */
1073 public void setPersistent(boolean persistent) {
1074 mPersistent = persistent;
1075 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001076
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001077 /**
1078 * Call this method after the user changes the preference, but before the
1079 * internal state is set. This allows the client to ignore the user value.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001080 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001081 * @param newValue The new value of this Preference.
1082 * @return True if the user value should be set as the preference
1083 * value (and persisted).
1084 */
1085 protected boolean callChangeListener(Object newValue) {
Filip Pavlis09557932017-03-03 16:54:22 +00001086 return mOnChangeListener == null || mOnChangeListener.onPreferenceChange(this, newValue);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001087 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001089 /**
1090 * Sets the callback to be invoked when this Preference is changed by the
1091 * user (but before the internal state has been updated).
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001092 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001093 * @param onPreferenceChangeListener The callback to be invoked.
1094 */
1095 public void setOnPreferenceChangeListener(OnPreferenceChangeListener onPreferenceChangeListener) {
1096 mOnChangeListener = onPreferenceChangeListener;
1097 }
1098
1099 /**
1100 * Returns the callback to be invoked when this Preference is changed by the
1101 * user (but before the internal state has been updated).
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001102 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001103 * @return The callback to be invoked.
1104 */
1105 public OnPreferenceChangeListener getOnPreferenceChangeListener() {
1106 return mOnChangeListener;
1107 }
1108
1109 /**
1110 * Sets the callback to be invoked when this Preference is clicked.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001111 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001112 * @param onPreferenceClickListener The callback to be invoked.
1113 */
1114 public void setOnPreferenceClickListener(OnPreferenceClickListener onPreferenceClickListener) {
1115 mOnClickListener = onPreferenceClickListener;
1116 }
1117
1118 /**
1119 * Returns the callback to be invoked when this Preference is clicked.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001120 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001121 * @return The callback to be invoked.
1122 */
1123 public OnPreferenceClickListener getOnPreferenceClickListener() {
1124 return mOnClickListener;
1125 }
1126
1127 /**
1128 * Called when a click should be performed.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001129 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001130 * @param preferenceScreen A {@link PreferenceScreen} whose hierarchy click
1131 * listener should be called in the proper order (between other
Filip Pavlisee3bc342017-03-13 16:58:24 +00001132 * processing). May be {@code null}.
Justin Koh37ae5582012-10-25 15:26:36 -07001133 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001134 */
Mathew Inwoodeac8d0a2018-08-17 13:51:26 +01001135 @UnsupportedAppUsage
Justin Koh37ae5582012-10-25 15:26:36 -07001136 public void performClick(PreferenceScreen preferenceScreen) {
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001138 if (!isEnabled()) {
1139 return;
1140 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001141
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001142 onClick();
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001143
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001144 if (mOnClickListener != null && mOnClickListener.onPreferenceClick(this)) {
1145 return;
1146 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001148 PreferenceManager preferenceManager = getPreferenceManager();
1149 if (preferenceManager != null) {
1150 PreferenceManager.OnPreferenceTreeClickListener listener = preferenceManager
1151 .getOnPreferenceTreeClickListener();
1152 if (preferenceScreen != null && listener != null
1153 && listener.onPreferenceTreeClick(preferenceScreen, this)) {
1154 return;
1155 }
1156 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001157
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001158 if (mIntent != null) {
1159 Context context = getContext();
1160 context.startActivity(mIntent);
1161 }
1162 }
John Reck014fea22011-06-15 16:46:36 -07001163
1164 /**
1165 * Allows a Preference to intercept key events without having focus.
1166 * For example, SeekBarPreference uses this to intercept +/- to adjust
1167 * the progress.
1168 * @return True if the Preference handled the key. Returns false by default.
1169 * @hide
1170 */
Mathew Inwood45d2c252018-09-14 12:35:36 +01001171 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
John Reck014fea22011-06-15 16:46:36 -07001172 public boolean onKey(View v, int keyCode, KeyEvent event) {
1173 return false;
1174 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001175
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001176 /**
Filip Pavlis09557932017-03-03 16:54:22 +00001177 * Returns the {@link android.content.Context} of this Preference.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001178 * Each Preference in a Preference hierarchy can be
1179 * from different Context (for example, if multiple activities provide preferences into a single
1180 * {@link PreferenceActivity}). This Context will be used to save the Preference values.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001181 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001182 * @return The Context of this Preference.
1183 */
1184 public Context getContext() {
1185 return mContext;
1186 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001187
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001188 /**
1189 * Returns the {@link SharedPreferences} where this Preference can read its
1190 * value(s). Usually, it's easier to use one of the helper read methods:
1191 * {@link #getPersistedBoolean(boolean)}, {@link #getPersistedFloat(float)},
1192 * {@link #getPersistedInt(int)}, {@link #getPersistedLong(long)},
1193 * {@link #getPersistedString(String)}. To save values, see
1194 * {@link #getEditor()}.
1195 * <p>
1196 * In some cases, writes to the {@link #getEditor()} will not be committed
1197 * right away and hence not show up in the returned
1198 * {@link SharedPreferences}, this is intended behavior to improve
1199 * performance.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001200 *
Filip Pavlisee3bc342017-03-13 16:58:24 +00001201 * @return the {@link SharedPreferences} where this Preference reads its value(s). If
1202 * this preference isn't attached to a Preference hierarchy or if
1203 * a {@link PreferenceDataStore} has been set, this method returns {@code null}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001204 * @see #getEditor()
Filip Pavlis09557932017-03-03 16:54:22 +00001205 * @see #setPreferenceDataStore(PreferenceDataStore)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001206 */
1207 public SharedPreferences getSharedPreferences() {
Filip Pavlis09557932017-03-03 16:54:22 +00001208 if (mPreferenceManager == null || getPreferenceDataStore() != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001209 return null;
1210 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001212 return mPreferenceManager.getSharedPreferences();
1213 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001215 /**
1216 * Returns an {@link SharedPreferences.Editor} where this Preference can
1217 * save its value(s). Usually it's easier to use one of the helper save
1218 * methods: {@link #persistBoolean(boolean)}, {@link #persistFloat(float)},
1219 * {@link #persistInt(int)}, {@link #persistLong(long)},
1220 * {@link #persistString(String)}. To read values, see
1221 * {@link #getSharedPreferences()}. If {@link #shouldCommit()} returns
1222 * true, it is this Preference's responsibility to commit.
1223 * <p>
1224 * In some cases, writes to this will not be committed right away and hence
1225 * not show up in the SharedPreferences, this is intended behavior to
1226 * improve performance.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001227 *
Filip Pavlisee3bc342017-03-13 16:58:24 +00001228 * @return a {@link SharedPreferences.Editor} where this preference saves its value(s). If
1229 * this preference isn't attached to a Preference hierarchy or if
1230 * a {@link PreferenceDataStore} has been set, this method returns {@code null}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001231 * @see #shouldCommit()
1232 * @see #getSharedPreferences()
Filip Pavlis09557932017-03-03 16:54:22 +00001233 * @see #setPreferenceDataStore(PreferenceDataStore)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001234 */
1235 public SharedPreferences.Editor getEditor() {
Filip Pavlis09557932017-03-03 16:54:22 +00001236 if (mPreferenceManager == null || getPreferenceDataStore() != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001237 return null;
1238 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001239
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001240 return mPreferenceManager.getEditor();
1241 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001242
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001243 /**
1244 * Returns whether the {@link Preference} should commit its saved value(s) in
1245 * {@link #getEditor()}. This may return false in situations where batch
1246 * committing is being done (by the manager) to improve performance.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001247 *
Filip Pavlisee3bc342017-03-13 16:58:24 +00001248 * <p>If this preference is using {@link PreferenceDataStore} this value is irrelevant.
Filip Pavlis09557932017-03-03 16:54:22 +00001249 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001250 * @return Whether the Preference should commit its saved value(s).
1251 * @see #getEditor()
1252 */
1253 public boolean shouldCommit() {
1254 if (mPreferenceManager == null) {
1255 return false;
1256 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001258 return mPreferenceManager.shouldCommit();
1259 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001261 /**
1262 * Compares Preference objects based on order (if set), otherwise alphabetically on the titles.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001263 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001264 * @param another The Preference to compare to this one.
1265 * @return 0 if the same; less than 0 if this Preference sorts ahead of <var>another</var>;
1266 * greater than 0 if this Preference sorts after <var>another</var>.
1267 */
Jeff Brown75af1712013-11-10 18:54:03 -08001268 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001269 public int compareTo(Preference another) {
Jeff Brown75af1712013-11-10 18:54:03 -08001270 if (mOrder != another.mOrder) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001271 // Do order comparison
Jeff Brown75af1712013-11-10 18:54:03 -08001272 return mOrder - another.mOrder;
Carsten Haugeb2e61e42013-02-04 14:45:20 +01001273 } else if (mTitle == another.mTitle) {
1274 // If titles are null or share same object comparison
1275 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001276 } else if (mTitle == null) {
1277 return 1;
1278 } else if (another.mTitle == null) {
1279 return -1;
1280 } else {
1281 // Do name comparison
1282 return CharSequences.compareToIgnoreCase(mTitle, another.mTitle);
1283 }
1284 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001286 /**
1287 * Sets the internal change listener.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001288 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001289 * @param listener The listener.
1290 * @see #notifyChanged()
1291 */
Mathew Inwoodeac8d0a2018-08-17 13:51:26 +01001292 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001293 final void setOnPreferenceChangeInternalListener(OnPreferenceChangeInternalListener listener) {
1294 mListener = listener;
1295 }
1296
1297 /**
1298 * Should be called when the data of this {@link Preference} has changed.
1299 */
1300 protected void notifyChanged() {
1301 if (mListener != null) {
1302 mListener.onPreferenceChange(this);
1303 }
1304 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001306 /**
1307 * Should be called when a Preference has been
1308 * added/removed from this group, or the ordering should be
1309 * re-evaluated.
1310 */
1311 protected void notifyHierarchyChanged() {
1312 if (mListener != null) {
1313 mListener.onPreferenceHierarchyChange(this);
1314 }
1315 }
1316
1317 /**
1318 * Gets the {@link PreferenceManager} that manages this Preference object's tree.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001319 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001320 * @return The {@link PreferenceManager}.
1321 */
1322 public PreferenceManager getPreferenceManager() {
1323 return mPreferenceManager;
1324 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001326 /**
1327 * Called when this Preference has been attached to a Preference hierarchy.
1328 * Make sure to call the super implementation.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001329 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001330 * @param preferenceManager The PreferenceManager of the hierarchy.
1331 */
1332 protected void onAttachedToHierarchy(PreferenceManager preferenceManager) {
1333 mPreferenceManager = preferenceManager;
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001335 mId = preferenceManager.getNextId();
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001337 dispatchSetInitialValue();
1338 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001340 /**
1341 * Called when the Preference hierarchy has been attached to the
Jason Monkb65b7102016-04-04 13:19:31 +00001342 * {@link PreferenceActivity}. This can also be called when this
1343 * Preference has been attached to a group that was already attached
1344 * to the {@link PreferenceActivity}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001345 */
1346 protected void onAttachedToActivity() {
1347 // At this point, the hierarchy that this preference is in is connected
1348 // with all other preferences.
1349 registerDependency();
1350 }
1351
Filip Pavliscba64582017-01-10 19:17:09 +00001352 /**
Filip Pavlisee3bc342017-03-13 16:58:24 +00001353 * Assigns a {@link PreferenceGroup} as the parent of this Preference. Set {@code null} to
1354 * remove the current parent.
Filip Pavliscba64582017-01-10 19:17:09 +00001355 *
Filip Pavlisee3bc342017-03-13 16:58:24 +00001356 * @param parentGroup Parent preference group of this Preference or {@code null} if none.
Filip Pavliscba64582017-01-10 19:17:09 +00001357 */
1358 void assignParent(@Nullable PreferenceGroup parentGroup) {
1359 mParentGroup = parentGroup;
1360 }
1361
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001362 private void registerDependency() {
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001363
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001364 if (TextUtils.isEmpty(mDependencyKey)) return;
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001365
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001366 Preference preference = findPreferenceInHierarchy(mDependencyKey);
1367 if (preference != null) {
1368 preference.registerDependent(this);
1369 } else {
1370 throw new IllegalStateException("Dependency \"" + mDependencyKey
1371 + "\" not found for preference \"" + mKey + "\" (title: \"" + mTitle + "\"");
1372 }
1373 }
1374
1375 private void unregisterDependency() {
1376 if (mDependencyKey != null) {
1377 final Preference oldDependency = findPreferenceInHierarchy(mDependencyKey);
1378 if (oldDependency != null) {
1379 oldDependency.unregisterDependent(this);
1380 }
1381 }
1382 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001384 /**
1385 * Finds a Preference in this hierarchy (the whole thing,
1386 * even above/below your {@link PreferenceScreen} screen break) with the given
1387 * key.
1388 * <p>
1389 * This only functions after we have been attached to a hierarchy.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001390 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001391 * @param key The key of the Preference to find.
1392 * @return The Preference that uses the given key.
1393 */
1394 protected Preference findPreferenceInHierarchy(String key) {
1395 if (TextUtils.isEmpty(key) || mPreferenceManager == null) {
1396 return null;
1397 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001398
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001399 return mPreferenceManager.findPreference(key);
1400 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001402 /**
1403 * Adds a dependent Preference on this Preference so we can notify it.
1404 * Usually, the dependent Preference registers itself (it's good for it to
1405 * know it depends on something), so please use
1406 * {@link Preference#setDependency(String)} on the dependent Preference.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001407 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001408 * @param dependent The dependent Preference that will be enabled/disabled
1409 * according to the state of this Preference.
1410 */
Mathew Inwoodeac8d0a2018-08-17 13:51:26 +01001411 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001412 private void registerDependent(Preference dependent) {
1413 if (mDependents == null) {
1414 mDependents = new ArrayList<Preference>();
1415 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001416
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001417 mDependents.add(dependent);
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001418
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001419 dependent.onDependencyChanged(this, shouldDisableDependents());
1420 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001421
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001422 /**
1423 * Removes a dependent Preference on this Preference.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001424 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001425 * @param dependent The dependent Preference that will be enabled/disabled
1426 * according to the state of this Preference.
1427 * @return Returns the same Preference object, for chaining multiple calls
1428 * into a single statement.
1429 */
1430 private void unregisterDependent(Preference dependent) {
1431 if (mDependents != null) {
1432 mDependents.remove(dependent);
1433 }
1434 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001435
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001436 /**
1437 * Notifies any listening dependents of a change that affects the
1438 * dependency.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001439 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001440 * @param disableDependents Whether this Preference should disable
1441 * its dependents.
1442 */
1443 public void notifyDependencyChange(boolean disableDependents) {
1444 final List<Preference> dependents = mDependents;
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001446 if (dependents == null) {
1447 return;
1448 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001449
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001450 final int dependentsCount = dependents.size();
1451 for (int i = 0; i < dependentsCount; i++) {
1452 dependents.get(i).onDependencyChanged(this, disableDependents);
1453 }
1454 }
1455
1456 /**
1457 * Called when the dependency changes.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001458 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001459 * @param dependency The Preference that this Preference depends on.
1460 * @param disableDependent Set true to disable this Preference.
1461 */
1462 public void onDependencyChanged(Preference dependency, boolean disableDependent) {
Michael Chanda53eca2009-03-27 17:46:36 -07001463 if (mDependencyMet == disableDependent) {
1464 mDependencyMet = !disableDependent;
1465
1466 // Enabled state can change dependent preferences' states, so notify
1467 notifyDependencyChange(shouldDisableDependents());
1468
1469 notifyChanged();
1470 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001471 }
Alan Viverette02f56802013-08-19 16:32:56 -07001472
1473 /**
1474 * Called when the implicit parent dependency changes.
1475 *
1476 * @param parent The Preference that this Preference depends on.
1477 * @param disableChild Set true to disable this Preference.
1478 */
1479 public void onParentChanged(Preference parent, boolean disableChild) {
1480 if (mParentDependencyMet == disableChild) {
1481 mParentDependencyMet = !disableChild;
1482
1483 // Enabled state can change dependent preferences' states, so notify
1484 notifyDependencyChange(shouldDisableDependents());
1485
1486 notifyChanged();
1487 }
1488 }
1489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001490 /**
1491 * Checks whether this preference's dependents should currently be
1492 * disabled.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001493 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001494 * @return True if the dependents should be disabled, otherwise false.
1495 */
1496 public boolean shouldDisableDependents() {
1497 return !isEnabled();
1498 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001500 /**
1501 * Sets the key of a Preference that this Preference will depend on. If that
1502 * Preference is not set or is off, this Preference will be disabled.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001503 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001504 * @param dependencyKey The key of the Preference that this depends on.
1505 */
1506 public void setDependency(String dependencyKey) {
1507 // Unregister the old dependency, if we had one
1508 unregisterDependency();
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 // Register the new
1511 mDependencyKey = dependencyKey;
1512 registerDependency();
1513 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001515 /**
1516 * Returns the key of the dependency on this Preference.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001517 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001518 * @return The key of the dependency.
1519 * @see #setDependency(String)
1520 */
1521 public String getDependency() {
1522 return mDependencyKey;
1523 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001524
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001525 /**
Filip Pavlisee3bc342017-03-13 16:58:24 +00001526 * Returns the {@link PreferenceGroup} which is this Preference assigned to or {@code null} if
1527 * this preference is not assigned to any group or is a root Preference.
Filip Pavliscba64582017-01-10 19:17:09 +00001528 *
Filip Pavlisee3bc342017-03-13 16:58:24 +00001529 * @return the parent PreferenceGroup or {@code null} if not attached to any
Filip Pavliscba64582017-01-10 19:17:09 +00001530 */
1531 @Nullable
1532 public PreferenceGroup getParent() {
1533 return mParentGroup;
1534 }
1535
1536 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001537 * Called when this Preference is being removed from the hierarchy. You
1538 * should remove any references to this Preference that you know about. Make
1539 * sure to call through to the superclass implementation.
1540 */
Tor Norbyec615c6f2015-03-02 10:11:44 -08001541 @CallSuper
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001542 protected void onPrepareForRemoval() {
1543 unregisterDependency();
1544 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001545
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001546 /**
1547 * Sets the default value for this Preference, which will be set either if
1548 * persistence is off or persistence is on and the preference is not found
1549 * in the persistent storage.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001550 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001551 * @param defaultValue The default value.
1552 */
1553 public void setDefaultValue(Object defaultValue) {
1554 mDefaultValue = defaultValue;
1555 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001556
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001557 private void dispatchSetInitialValue() {
Filip Pavlis09557932017-03-03 16:54:22 +00001558 if (getPreferenceDataStore() != null) {
1559 onSetInitialValue(true, mDefaultValue);
1560 return;
1561 }
1562
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 // By now, we know if we are persistent.
1564 final boolean shouldPersist = shouldPersist();
1565 if (!shouldPersist || !getSharedPreferences().contains(mKey)) {
1566 if (mDefaultValue != null) {
1567 onSetInitialValue(false, mDefaultValue);
1568 }
1569 } else {
1570 onSetInitialValue(true, null);
1571 }
1572 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001573
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001574 /**
Filip Pavlisfd596452017-03-01 18:50:00 +00001575 * Implement this to set the initial value of the Preference.
Filip Pavlis09557932017-03-03 16:54:22 +00001576 *
1577 * <p>If <var>restorePersistedValue</var> is true, you should restore the
Filip Pavlisfd596452017-03-01 18:50:00 +00001578 * Preference value from the {@link android.content.SharedPreferences}. If
1579 * <var>restorePersistedValue</var> is false, you should set the Preference
1580 * value to defaultValue that is given (and possibly store to SharedPreferences
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001581 * if {@link #shouldPersist()} is true).
Filip Pavlis09557932017-03-03 16:54:22 +00001582 *
1583 * <p>In case of using {@link PreferenceDataStore}, the <var>restorePersistedValue</var> is
Filip Pavlisee3bc342017-03-13 16:58:24 +00001584 * always {@code true}. But the default value (if provided) is set.
Filip Pavlis09557932017-03-03 16:54:22 +00001585 *
1586 * <p>This may not always be called. One example is if it should not persist
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001587 * but there is no default value given.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001588 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001589 * @param restorePersistedValue True to restore the persisted value;
1590 * false to use the given <var>defaultValue</var>.
1591 * @param defaultValue The default value for this Preference. Only use this
1592 * if <var>restorePersistedValue</var> is false.
1593 */
1594 protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
1595 }
1596
1597 private void tryCommit(SharedPreferences.Editor editor) {
1598 if (mPreferenceManager.shouldCommit()) {
Brad Fitzpatrickdd644c12010-10-10 10:58:47 -07001599 try {
1600 editor.apply();
1601 } catch (AbstractMethodError unused) {
1602 // The app injected its own pre-Gingerbread
1603 // SharedPreferences.Editor implementation without
1604 // an apply method.
1605 editor.commit();
1606 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001607 }
1608 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001609
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001610 /**
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001611 * Attempts to persist a String if this Preference is persistent.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001612 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001613 * @param value The value to persist.
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001614 * @return True if this Preference is persistent. (This is not whether the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001615 * value was persisted, since we may not necessarily commit if there
1616 * will be a batch commit later.)
1617 * @see #getPersistedString(String)
1618 */
1619 protected boolean persistString(String value) {
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001620 if (!shouldPersist()) {
1621 return false;
1622 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001623
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001624 // Shouldn't store null
1625 if (TextUtils.equals(value, getPersistedString(null))) {
1626 // It's already there, so the same as persisting
1627 return true;
1628 }
1629
1630 PreferenceDataStore dataStore = getPreferenceDataStore();
1631 if (dataStore != null) {
1632 dataStore.putString(mKey, value);
1633 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001634 SharedPreferences.Editor editor = mPreferenceManager.getEditor();
1635 editor.putString(mKey, value);
1636 tryCommit(editor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001637 }
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001638 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001639 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001640
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001641 /**
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001642 * Attempts to get a persisted String if this Preference is persistent.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001643 *
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001644 * @param defaultReturnValue The default value to return if either this
1645 * Preference is not persistent or this Preference is not present.
1646 * @return The value from the data store or the default return
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001647 * value.
1648 * @see #persistString(String)
1649 */
1650 protected String getPersistedString(String defaultReturnValue) {
1651 if (!shouldPersist()) {
1652 return defaultReturnValue;
1653 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001654
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001655 PreferenceDataStore dataStore = getPreferenceDataStore();
1656 if (dataStore != null) {
1657 return dataStore.getString(mKey, defaultReturnValue);
1658 }
1659
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001660 return mPreferenceManager.getSharedPreferences().getString(mKey, defaultReturnValue);
1661 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001662
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001663 /**
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001664 * Attempts to persist a set of Strings if this Preference is persistent.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001665 *
Adam Powell212db7d2010-04-08 16:24:46 -07001666 * @param values The values to persist.
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001667 * @return True if this Preference is persistent. (This is not whether the
Adam Powell212db7d2010-04-08 16:24:46 -07001668 * value was persisted, since we may not necessarily commit if there
1669 * will be a batch commit later.)
Adam Powell5c2f8392016-02-23 16:06:42 -08001670 * @see #getPersistedStringSet(Set)
Adam Powell212db7d2010-04-08 16:24:46 -07001671 */
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001672 public boolean persistStringSet(Set<String> values) {
1673 if (!shouldPersist()) {
1674 return false;
1675 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001676
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001677 // Shouldn't store null
1678 if (values.equals(getPersistedStringSet(null))) {
1679 // It's already there, so the same as persisting
1680 return true;
1681 }
1682
1683 PreferenceDataStore dataStore = getPreferenceDataStore();
1684 if (dataStore != null) {
1685 dataStore.putStringSet(mKey, values);
1686 } else {
Adam Powell212db7d2010-04-08 16:24:46 -07001687 SharedPreferences.Editor editor = mPreferenceManager.getEditor();
1688 editor.putStringSet(mKey, values);
1689 tryCommit(editor);
Adam Powell212db7d2010-04-08 16:24:46 -07001690 }
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001691 return true;
Adam Powell212db7d2010-04-08 16:24:46 -07001692 }
1693
1694 /**
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001695 * Attempts to get a persisted set of Strings if this Preference is persistent.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001696 *
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001697 * @param defaultReturnValue The default value to return if either this
1698 * Preference is not persistent or this Preference is not present.
1699 * @return The value from the data store or the default return
Adam Powell212db7d2010-04-08 16:24:46 -07001700 * value.
1701 * @see #persistStringSet(Set)
Adam Powell212db7d2010-04-08 16:24:46 -07001702 */
Adam Powell5c2f8392016-02-23 16:06:42 -08001703 public Set<String> getPersistedStringSet(Set<String> defaultReturnValue) {
Adam Powell212db7d2010-04-08 16:24:46 -07001704 if (!shouldPersist()) {
1705 return defaultReturnValue;
1706 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001707
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001708 PreferenceDataStore dataStore = getPreferenceDataStore();
1709 if (dataStore != null) {
1710 return dataStore.getStringSet(mKey, defaultReturnValue);
1711 }
1712
Adam Powell212db7d2010-04-08 16:24:46 -07001713 return mPreferenceManager.getSharedPreferences().getStringSet(mKey, defaultReturnValue);
1714 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001715
Adam Powell212db7d2010-04-08 16:24:46 -07001716 /**
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001717 * Attempts to persist an int if this Preference is persistent.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001718 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001719 * @param value The value to persist.
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001720 * @return True if this Preference is persistent. (This is not whether the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001721 * value was persisted, since we may not necessarily commit if there
1722 * will be a batch commit later.)
1723 * @see #persistString(String)
1724 * @see #getPersistedInt(int)
1725 */
1726 protected boolean persistInt(int value) {
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001727 if (!shouldPersist()) {
1728 return false;
1729 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001730
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001731 if (value == getPersistedInt(~value)) {
1732 // It's already there, so the same as persisting
1733 return true;
1734 }
1735
1736 PreferenceDataStore dataStore = getPreferenceDataStore();
1737 if (dataStore != null) {
1738 dataStore.putInt(mKey, value);
1739 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001740 SharedPreferences.Editor editor = mPreferenceManager.getEditor();
1741 editor.putInt(mKey, value);
1742 tryCommit(editor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001743 }
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001744 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001745 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001746
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001747 /**
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001748 * Attempts to get a persisted int if this Preference is persistent.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001749 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001750 * @param defaultReturnValue The default value to return if either this
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001751 * Preference is not persistent or this Preference is not present.
1752 * @return The value from the data store or the default return
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001753 * value.
1754 * @see #getPersistedString(String)
1755 * @see #persistInt(int)
1756 */
1757 protected int getPersistedInt(int defaultReturnValue) {
1758 if (!shouldPersist()) {
1759 return defaultReturnValue;
1760 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001761
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001762 PreferenceDataStore dataStore = getPreferenceDataStore();
1763 if (dataStore != null) {
1764 return dataStore.getInt(mKey, defaultReturnValue);
1765 }
1766
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001767 return mPreferenceManager.getSharedPreferences().getInt(mKey, defaultReturnValue);
1768 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001770 /**
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001771 * Attempts to persist a long if this Preference is persistent.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001772 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001773 * @param value The value to persist.
1774 * @return True if this Preference is persistent. (This is not whether the
1775 * value was persisted, since we may not necessarily commit if there
1776 * will be a batch commit later.)
1777 * @see #persistString(String)
1778 * @see #getPersistedFloat(float)
1779 */
1780 protected boolean persistFloat(float value) {
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001781 if (!shouldPersist()) {
1782 return false;
1783 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001784
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001785 if (value == getPersistedFloat(Float.NaN)) {
1786 // It's already there, so the same as persisting
1787 return true;
1788 }
1789
1790 PreferenceDataStore dataStore = getPreferenceDataStore();
1791 if (dataStore != null) {
1792 dataStore.putFloat(mKey, value);
1793 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001794 SharedPreferences.Editor editor = mPreferenceManager.getEditor();
1795 editor.putFloat(mKey, value);
1796 tryCommit(editor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001797 }
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001798 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001799 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001800
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001801 /**
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001802 * Attempts to get a persisted float if this Preference is persistent.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001803 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001804 * @param defaultReturnValue The default value to return if either this
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001805 * Preference is not persistent or this Preference is not present.
1806 * @return The value from the data store or the default return
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001807 * value.
1808 * @see #getPersistedString(String)
1809 * @see #persistFloat(float)
1810 */
1811 protected float getPersistedFloat(float defaultReturnValue) {
1812 if (!shouldPersist()) {
1813 return defaultReturnValue;
1814 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001815
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001816 PreferenceDataStore dataStore = getPreferenceDataStore();
1817 if (dataStore != null) {
1818 return dataStore.getFloat(mKey, defaultReturnValue);
1819 }
1820
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001821 return mPreferenceManager.getSharedPreferences().getFloat(mKey, defaultReturnValue);
1822 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001823
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001824 /**
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001825 * Attempts to persist a long if this Preference is persistent.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001826 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001827 * @param value The value to persist.
1828 * @return True if this Preference is persistent. (This is not whether the
1829 * value was persisted, since we may not necessarily commit if there
1830 * will be a batch commit later.)
1831 * @see #persistString(String)
1832 * @see #getPersistedLong(long)
1833 */
1834 protected boolean persistLong(long value) {
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001835 if (!shouldPersist()) {
1836 return false;
1837 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001838
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001839 if (value == getPersistedLong(~value)) {
1840 // It's already there, so the same as persisting
1841 return true;
1842 }
1843
1844 PreferenceDataStore dataStore = getPreferenceDataStore();
1845 if (dataStore != null) {
1846 dataStore.putLong(mKey, value);
1847 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001848 SharedPreferences.Editor editor = mPreferenceManager.getEditor();
1849 editor.putLong(mKey, value);
1850 tryCommit(editor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001851 }
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001852 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001853 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001854
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001855 /**
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001856 * Attempts to get a persisted long if this Preference is persistent.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001857 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001858 * @param defaultReturnValue The default value to return if either this
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001859 * Preference is not persistent or this Preference is not present.
1860 * @return The value from the data store or the default return
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001861 * value.
1862 * @see #getPersistedString(String)
1863 * @see #persistLong(long)
1864 */
1865 protected long getPersistedLong(long defaultReturnValue) {
1866 if (!shouldPersist()) {
1867 return defaultReturnValue;
1868 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001869
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001870 PreferenceDataStore dataStore = getPreferenceDataStore();
1871 if (dataStore != null) {
1872 return dataStore.getLong(mKey, defaultReturnValue);
1873 }
1874
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001875 return mPreferenceManager.getSharedPreferences().getLong(mKey, defaultReturnValue);
1876 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001877
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001878 /**
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001879 * Attempts to persist a boolean if this Preference is persistent.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001880 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001881 * @param value The value to persist.
1882 * @return True if this Preference is persistent. (This is not whether the
1883 * value was persisted, since we may not necessarily commit if there
1884 * will be a batch commit later.)
1885 * @see #persistString(String)
1886 * @see #getPersistedBoolean(boolean)
1887 */
1888 protected boolean persistBoolean(boolean value) {
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001889 if (!shouldPersist()) {
1890 return false;
1891 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001892
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001893 if (value == getPersistedBoolean(!value)) {
1894 // It's already there, so the same as persisting
1895 return true;
1896 }
1897
1898 PreferenceDataStore dataStore = getPreferenceDataStore();
1899 if (dataStore != null) {
1900 dataStore.putBoolean(mKey, value);
1901 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001902 SharedPreferences.Editor editor = mPreferenceManager.getEditor();
1903 editor.putBoolean(mKey, value);
1904 tryCommit(editor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001905 }
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001906 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001907 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001908
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001909 /**
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001910 * Attempts to get a persisted boolean if this Preference is persistent.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001911 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001912 * @param defaultReturnValue The default value to return if either this
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001913 * Preference is not persistent or this Preference is not present.
1914 * @return The value from the data store or the default return
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001915 * value.
1916 * @see #getPersistedString(String)
1917 * @see #persistBoolean(boolean)
1918 */
1919 protected boolean getPersistedBoolean(boolean defaultReturnValue) {
1920 if (!shouldPersist()) {
1921 return defaultReturnValue;
1922 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001923
Filip Pavlis0b0c6cb2016-11-16 15:58:28 +00001924 PreferenceDataStore dataStore = getPreferenceDataStore();
1925 if (dataStore != null) {
1926 return dataStore.getBoolean(mKey, defaultReturnValue);
1927 }
1928
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001929 return mPreferenceManager.getSharedPreferences().getBoolean(mKey, defaultReturnValue);
1930 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001931
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001932 @Override
1933 public String toString() {
1934 return getFilterableStringBuilder().toString();
1935 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001936
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001937 /**
1938 * Returns the text that will be used to filter this Preference depending on
1939 * user input.
1940 * <p>
1941 * If overridding and calling through to the superclass, make sure to prepend
1942 * your additions with a space.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001943 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001944 * @return Text as a {@link StringBuilder} that will be used to filter this
1945 * preference. By default, this is the title and summary
1946 * (concatenated with a space).
1947 */
1948 StringBuilder getFilterableStringBuilder() {
1949 StringBuilder sb = new StringBuilder();
1950 CharSequence title = getTitle();
1951 if (!TextUtils.isEmpty(title)) {
1952 sb.append(title).append(' ');
1953 }
1954 CharSequence summary = getSummary();
1955 if (!TextUtils.isEmpty(summary)) {
1956 sb.append(summary).append(' ');
1957 }
Tammo Spalink0bb99602009-09-08 18:30:33 +08001958 if (sb.length() > 0) {
1959 // Drop the last space
1960 sb.setLength(sb.length() - 1);
1961 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001962 return sb;
1963 }
1964
1965 /**
1966 * Store this Preference hierarchy's frozen state into the given container.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001967 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001968 * @param container The Bundle in which to save the instance of this Preference.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001969 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001970 * @see #restoreHierarchyState
1971 * @see #onSaveInstanceState
1972 */
1973 public void saveHierarchyState(Bundle container) {
1974 dispatchSaveInstanceState(container);
1975 }
1976
1977 /**
Filip Pavlis09557932017-03-03 16:54:22 +00001978 * Called by {@link #saveHierarchyState} to store the instance for this Preference and its
1979 * children. May be overridden to modify how the save happens for children. For example, some
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001980 * Preference objects may want to not store an instance for their children.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001981 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001982 * @param container The Bundle in which to save the instance of this Preference.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07001983 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001984 * @see #saveHierarchyState
1985 * @see #onSaveInstanceState
1986 */
1987 void dispatchSaveInstanceState(Bundle container) {
1988 if (hasKey()) {
1989 mBaseMethodCalled = false;
1990 Parcelable state = onSaveInstanceState();
1991 if (!mBaseMethodCalled) {
1992 throw new IllegalStateException(
1993 "Derived class did not call super.onSaveInstanceState()");
1994 }
1995 if (state != null) {
1996 container.putParcelable(mKey, state);
1997 }
1998 }
1999 }
2000
2001 /**
2002 * Hook allowing a Preference to generate a representation of its internal
2003 * state that can later be used to create a new instance with that same
2004 * state. This state should only contain information that is not persistent
2005 * or can be reconstructed later.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07002006 *
Filip Pavlisee3bc342017-03-13 16:58:24 +00002007 * @return A Parcelable object containing the current dynamic state of this Preference, or
2008 * {@code null} if there is nothing interesting to save. The default implementation
2009 * returns {@code null}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002010 * @see #onRestoreInstanceState
2011 * @see #saveHierarchyState
2012 */
2013 protected Parcelable onSaveInstanceState() {
2014 mBaseMethodCalled = true;
2015 return BaseSavedState.EMPTY_STATE;
2016 }
2017
2018 /**
2019 * Restore this Preference hierarchy's previously saved state from the given container.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07002020 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002021 * @param container The Bundle that holds the previously saved state.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07002022 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002023 * @see #saveHierarchyState
2024 * @see #onRestoreInstanceState
2025 */
2026 public void restoreHierarchyState(Bundle container) {
2027 dispatchRestoreInstanceState(container);
2028 }
2029
2030 /**
2031 * Called by {@link #restoreHierarchyState} to retrieve the saved state for this
2032 * Preference and its children. May be overridden to modify how restoring
2033 * happens to the children of a Preference. For example, some Preference objects may
2034 * not want to save state for their children.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07002035 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002036 * @param container The Bundle that holds the previously saved state.
2037 * @see #restoreHierarchyState
2038 * @see #onRestoreInstanceState
2039 */
2040 void dispatchRestoreInstanceState(Bundle container) {
2041 if (hasKey()) {
2042 Parcelable state = container.getParcelable(mKey);
2043 if (state != null) {
2044 mBaseMethodCalled = false;
2045 onRestoreInstanceState(state);
2046 if (!mBaseMethodCalled) {
2047 throw new IllegalStateException(
2048 "Derived class did not call super.onRestoreInstanceState()");
2049 }
2050 }
2051 }
2052 }
2053
2054 /**
Filip Pavlisee3bc342017-03-13 16:58:24 +00002055 * Hook allowing a Preference to re-apply a representation of its internal state that had
2056 * previously been generated by {@link #onSaveInstanceState}. This function will never be called
2057 * with a {@code null} state.
Tony Mantler9a6b11b2016-09-13 15:53:35 -07002058 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002059 * @param state The saved state that had previously been returned by
2060 * {@link #onSaveInstanceState}.
2061 * @see #onSaveInstanceState
2062 * @see #restoreHierarchyState
2063 */
2064 protected void onRestoreInstanceState(Parcelable state) {
2065 mBaseMethodCalled = true;
2066 if (state != BaseSavedState.EMPTY_STATE && state != null) {
2067 throw new IllegalArgumentException("Wrong state class -- expecting Preference State");
2068 }
2069 }
2070
2071 /**
2072 * A base class for managing the instance state of a {@link Preference}.
2073 */
2074 public static class BaseSavedState extends AbsSavedState {
2075 public BaseSavedState(Parcel source) {
2076 super(source);
2077 }
2078
2079 public BaseSavedState(Parcelable superState) {
2080 super(superState);
2081 }
Tony Mantler9a6b11b2016-09-13 15:53:35 -07002082
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002083 public static final Parcelable.Creator<BaseSavedState> CREATOR =
2084 new Parcelable.Creator<BaseSavedState>() {
Tony Mantler9a6b11b2016-09-13 15:53:35 -07002085 public BaseSavedState createFromParcel(Parcel in) {
2086 return new BaseSavedState(in);
2087 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002088
Tony Mantler9a6b11b2016-09-13 15:53:35 -07002089 public BaseSavedState[] newArray(int size) {
2090 return new BaseSavedState[size];
2091 }
2092 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002093 }
2094
2095}