blob: bb771d721d83010ce027e7a353a2655cef6150eb [file] [log] [blame]
Adam Powellbe0a4532010-11-29 17:47:48 -08001/*
2 * Copyright (C) 2010 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 Norbye7b9c9122013-05-30 16:48:33 -070019import android.annotation.StringRes;
Mathew Inwoodf2217132018-08-17 13:41:55 +010020import android.annotation.UnsupportedAppUsage;
Adam Powellbe0a4532010-11-29 17:47:48 -080021import android.content.Context;
22import android.content.SharedPreferences;
23import android.content.res.TypedArray;
24import android.os.Parcel;
25import android.os.Parcelable;
Amith Yamasanib2515882013-09-09 14:46:07 -070026import android.text.TextUtils;
Adam Powellbe0a4532010-11-29 17:47:48 -080027import android.util.AttributeSet;
28import android.view.View;
Adam Powellbe0a4532010-11-29 17:47:48 -080029import android.widget.TextView;
30
31/**
32 * Common base class for preferences that have two selectable states, persist a
33 * boolean value in SharedPreferences, and may have dependent preferences that are
34 * enabled/disabled based on the current state.
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +000035 *
36 * @deprecated Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
37 * <a href="{@docRoot}reference/androidx/preference/package-summary.html">
38 * Preference Library</a> for consistent behavior across all devices. For more information on
39 * using the AndroidX Preference Library see
40 * <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a>.
Adam Powellbe0a4532010-11-29 17:47:48 -080041 */
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +000042@Deprecated
Adam Powellbe0a4532010-11-29 17:47:48 -080043public abstract class TwoStatePreference extends Preference {
44
45 private CharSequence mSummaryOn;
46 private CharSequence mSummaryOff;
47 boolean mChecked;
Adam Powellc1b07212012-08-10 14:20:14 -070048 private boolean mCheckedSet;
Adam Powellbe0a4532010-11-29 17:47:48 -080049 private boolean mDisableDependentsState;
50
Alan Viverette617feb92013-09-09 18:09:13 -070051 public TwoStatePreference(
52 Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
53 super(context, attrs, defStyleAttr, defStyleRes);
54 }
Svetoslav Ganov5c3ea062011-07-22 18:52:56 -070055
Alan Viverette617feb92013-09-09 18:09:13 -070056 public TwoStatePreference(Context context, AttributeSet attrs, int defStyleAttr) {
57 this(context, attrs, defStyleAttr, 0);
Adam Powellbe0a4532010-11-29 17:47:48 -080058 }
59
60 public TwoStatePreference(Context context, AttributeSet attrs) {
Svetoslav Ganov5c3ea062011-07-22 18:52:56 -070061 this(context, attrs, 0);
Adam Powellbe0a4532010-11-29 17:47:48 -080062 }
63
64 public TwoStatePreference(Context context) {
Svetoslav Ganov5c3ea062011-07-22 18:52:56 -070065 this(context, null);
Adam Powellbe0a4532010-11-29 17:47:48 -080066 }
67
68 @Override
69 protected void onClick() {
70 super.onClick();
71
Alan Viverette996a6382014-09-02 16:35:45 -070072 final boolean newValue = !isChecked();
73 if (callChangeListener(newValue)) {
74 setChecked(newValue);
Adam Powellbe0a4532010-11-29 17:47:48 -080075 }
Adam Powellbe0a4532010-11-29 17:47:48 -080076 }
77
78 /**
79 * Sets the checked state and saves it to the {@link SharedPreferences}.
80 *
81 * @param checked The checked state.
82 */
83 public void setChecked(boolean checked) {
Adam Powellc1b07212012-08-10 14:20:14 -070084 // Always persist/notify the first time; don't assume the field's default of false.
85 final boolean changed = mChecked != checked;
86 if (changed || !mCheckedSet) {
Adam Powellbe0a4532010-11-29 17:47:48 -080087 mChecked = checked;
Adam Powellc1b07212012-08-10 14:20:14 -070088 mCheckedSet = true;
Adam Powellbe0a4532010-11-29 17:47:48 -080089 persistBoolean(checked);
Adam Powellc1b07212012-08-10 14:20:14 -070090 if (changed) {
91 notifyDependencyChange(shouldDisableDependents());
92 notifyChanged();
93 }
Adam Powellbe0a4532010-11-29 17:47:48 -080094 }
95 }
96
97 /**
98 * Returns the checked state.
99 *
100 * @return The checked state.
101 */
102 public boolean isChecked() {
103 return mChecked;
104 }
105
106 @Override
107 public boolean shouldDisableDependents() {
108 boolean shouldDisable = mDisableDependentsState ? mChecked : !mChecked;
109 return shouldDisable || super.shouldDisableDependents();
110 }
111
112 /**
113 * Sets the summary to be shown when checked.
114 *
115 * @param summary The summary to be shown when checked.
116 */
117 public void setSummaryOn(CharSequence summary) {
118 mSummaryOn = summary;
119 if (isChecked()) {
120 notifyChanged();
121 }
122 }
123
124 /**
125 * @see #setSummaryOn(CharSequence)
126 * @param summaryResId The summary as a resource.
127 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700128 public void setSummaryOn(@StringRes int summaryResId) {
Adam Powellbe0a4532010-11-29 17:47:48 -0800129 setSummaryOn(getContext().getString(summaryResId));
130 }
131
132 /**
133 * Returns the summary to be shown when checked.
134 * @return The summary.
135 */
136 public CharSequence getSummaryOn() {
137 return mSummaryOn;
138 }
139
140 /**
141 * Sets the summary to be shown when unchecked.
142 *
143 * @param summary The summary to be shown when unchecked.
144 */
145 public void setSummaryOff(CharSequence summary) {
146 mSummaryOff = summary;
147 if (!isChecked()) {
148 notifyChanged();
149 }
150 }
151
152 /**
153 * @see #setSummaryOff(CharSequence)
154 * @param summaryResId The summary as a resource.
155 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700156 public void setSummaryOff(@StringRes int summaryResId) {
Adam Powellbe0a4532010-11-29 17:47:48 -0800157 setSummaryOff(getContext().getString(summaryResId));
158 }
159
160 /**
161 * Returns the summary to be shown when unchecked.
162 * @return The summary.
163 */
164 public CharSequence getSummaryOff() {
165 return mSummaryOff;
166 }
167
168 /**
169 * Returns whether dependents are disabled when this preference is on ({@code true})
170 * or when this preference is off ({@code false}).
171 *
172 * @return Whether dependents are disabled when this preference is on ({@code true})
173 * or when this preference is off ({@code false}).
174 */
175 public boolean getDisableDependentsState() {
176 return mDisableDependentsState;
177 }
178
179 /**
180 * Sets whether dependents are disabled when this preference is on ({@code true})
181 * or when this preference is off ({@code false}).
182 *
183 * @param disableDependentsState The preference state that should disable dependents.
184 */
185 public void setDisableDependentsState(boolean disableDependentsState) {
186 mDisableDependentsState = disableDependentsState;
187 }
188
189 @Override
190 protected Object onGetDefaultValue(TypedArray a, int index) {
191 return a.getBoolean(index, false);
192 }
193
194 @Override
195 protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
196 setChecked(restoreValue ? getPersistedBoolean(mChecked)
197 : (Boolean) defaultValue);
198 }
199
Adam Powellbe0a4532010-11-29 17:47:48 -0800200 /**
201 * Sync a summary view contained within view's subhierarchy with the correct summary text.
202 * @param view View where a summary should be located
203 */
Mathew Inwoodf2217132018-08-17 13:41:55 +0100204 @UnsupportedAppUsage
Adam Powellbe0a4532010-11-29 17:47:48 -0800205 void syncSummaryView(View view) {
206 // Sync the summary view
207 TextView summaryView = (TextView) view.findViewById(com.android.internal.R.id.summary);
208 if (summaryView != null) {
209 boolean useDefaultSummary = true;
Amith Yamasanib2515882013-09-09 14:46:07 -0700210 if (mChecked && !TextUtils.isEmpty(mSummaryOn)) {
Adam Powellbe0a4532010-11-29 17:47:48 -0800211 summaryView.setText(mSummaryOn);
212 useDefaultSummary = false;
Amith Yamasanib2515882013-09-09 14:46:07 -0700213 } else if (!mChecked && !TextUtils.isEmpty(mSummaryOff)) {
Adam Powellbe0a4532010-11-29 17:47:48 -0800214 summaryView.setText(mSummaryOff);
215 useDefaultSummary = false;
216 }
217
218 if (useDefaultSummary) {
219 final CharSequence summary = getSummary();
Amith Yamasanib2515882013-09-09 14:46:07 -0700220 if (!TextUtils.isEmpty(summary)) {
Adam Powellbe0a4532010-11-29 17:47:48 -0800221 summaryView.setText(summary);
222 useDefaultSummary = false;
223 }
224 }
225
226 int newVisibility = View.GONE;
227 if (!useDefaultSummary) {
228 // Someone has written to it
229 newVisibility = View.VISIBLE;
230 }
231 if (newVisibility != summaryView.getVisibility()) {
232 summaryView.setVisibility(newVisibility);
233 }
234 }
235 }
236
237 @Override
238 protected Parcelable onSaveInstanceState() {
239 final Parcelable superState = super.onSaveInstanceState();
240 if (isPersistent()) {
241 // No need to save instance state since it's persistent
242 return superState;
243 }
244
245 final SavedState myState = new SavedState(superState);
246 myState.checked = isChecked();
247 return myState;
248 }
249
250 @Override
251 protected void onRestoreInstanceState(Parcelable state) {
252 if (state == null || !state.getClass().equals(SavedState.class)) {
253 // Didn't save state for us in onSaveInstanceState
254 super.onRestoreInstanceState(state);
255 return;
256 }
257
258 SavedState myState = (SavedState) state;
259 super.onRestoreInstanceState(myState.getSuperState());
260 setChecked(myState.checked);
261 }
262
263 static class SavedState extends BaseSavedState {
264 boolean checked;
265
266 public SavedState(Parcel source) {
267 super(source);
268 checked = source.readInt() == 1;
269 }
270
271 @Override
272 public void writeToParcel(Parcel dest, int flags) {
273 super.writeToParcel(dest, flags);
274 dest.writeInt(checked ? 1 : 0);
275 }
276
277 public SavedState(Parcelable superState) {
278 super(superState);
279 }
280
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700281 public static final @android.annotation.NonNull Parcelable.Creator<SavedState> CREATOR =
Adam Powellbe0a4532010-11-29 17:47:48 -0800282 new Parcelable.Creator<SavedState>() {
283 public SavedState createFromParcel(Parcel in) {
284 return new SavedState(in);
285 }
286
287 public SavedState[] newArray(int size) {
288 return new SavedState[size];
289 }
290 };
291 }
Adam Powellbe0a4532010-11-29 17:47:48 -0800292}