blob: 4b854ade025edd0c1ef6ec2ef218fe72fb32a51c [file] [log] [blame]
Dianne Hackborn7746f912012-04-26 15:34:57 -07001/*
2 * Copyright (C) 2012 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.ArrayRes;
Dianne Hackborn7746f912012-04-26 15:34:57 -070020import android.app.AlertDialog.Builder;
21import android.content.Context;
22import android.content.DialogInterface;
23import android.content.res.TypedArray;
24import android.os.Parcel;
25import android.os.Parcelable;
26import android.util.AttributeSet;
27
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +000028import java.util.Arrays;
29
Dianne Hackborn7746f912012-04-26 15:34:57 -070030/**
31 * @hide
32 * A {@link Preference} that displays a list of entries as
33 * a dialog which allow the user to toggle each individually on and off.
34 *
35 * @attr ref android.R.styleable#ListPreference_entries
36 * @attr ref android.R.styleable#ListPreference_entryValues
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +000037 *
38 * @deprecated Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
39 * <a href="{@docRoot}reference/androidx/preference/package-summary.html">
40 * Preference Library</a> for consistent behavior across all devices. For more information on
41 * using the AndroidX Preference Library see
42 * <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a>.
Dianne Hackborn7746f912012-04-26 15:34:57 -070043 */
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +000044@Deprecated
Dianne Hackborn7746f912012-04-26 15:34:57 -070045public class MultiCheckPreference extends DialogPreference {
46 private CharSequence[] mEntries;
47 private String[] mEntryValues;
48 private boolean[] mSetValues;
49 private boolean[] mOrigValues;
50 private String mSummary;
Alan Viverette617feb92013-09-09 18:09:13 -070051
52 public MultiCheckPreference(
53 Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
54 super(context, attrs, defStyleAttr, defStyleRes);
55
56 TypedArray a = context.obtainStyledAttributes(
57 attrs, com.android.internal.R.styleable.ListPreference, defStyleAttr, defStyleRes);
Dianne Hackborn7746f912012-04-26 15:34:57 -070058 mEntries = a.getTextArray(com.android.internal.R.styleable.ListPreference_entries);
59 if (mEntries != null) {
60 setEntries(mEntries);
61 }
62 setEntryValuesCS(a.getTextArray(
63 com.android.internal.R.styleable.ListPreference_entryValues));
64 a.recycle();
65
66 /* Retrieve the Preference summary attribute since it's private
67 * in the Preference class.
68 */
69 a = context.obtainStyledAttributes(attrs,
70 com.android.internal.R.styleable.Preference, 0, 0);
71 mSummary = a.getString(com.android.internal.R.styleable.Preference_summary);
72 a.recycle();
73 }
74
Alan Viverette617feb92013-09-09 18:09:13 -070075 public MultiCheckPreference(Context context, AttributeSet attrs, int defStyleAttr) {
76 this(context, attrs, defStyleAttr, 0);
77 }
78
79 public MultiCheckPreference(Context context, AttributeSet attrs) {
Alan Viverette599d2a42013-09-16 13:48:29 -070080 this(context, attrs, com.android.internal.R.attr.dialogPreferenceStyle);
Alan Viverette617feb92013-09-09 18:09:13 -070081 }
82
Dianne Hackborn7746f912012-04-26 15:34:57 -070083 public MultiCheckPreference(Context context) {
84 this(context, null);
85 }
86
87 /**
88 * Sets the human-readable entries to be shown in the list. This will be
89 * shown in subsequent dialogs.
90 * <p>
91 * Each entry must have a corresponding index in
92 * {@link #setEntryValues(CharSequence[])}.
93 *
94 * @param entries The entries.
95 * @see #setEntryValues(CharSequence[])
96 */
97 public void setEntries(CharSequence[] entries) {
98 mEntries = entries;
99 mSetValues = new boolean[entries.length];
100 mOrigValues = new boolean[entries.length];
101 }
102
103 /**
104 * @see #setEntries(CharSequence[])
105 * @param entriesResId The entries array as a resource.
106 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700107 public void setEntries(@ArrayRes int entriesResId) {
Dianne Hackborn7746f912012-04-26 15:34:57 -0700108 setEntries(getContext().getResources().getTextArray(entriesResId));
109 }
110
111 /**
112 * The list of entries to be shown in the list in subsequent dialogs.
113 *
114 * @return The list as an array.
115 */
116 public CharSequence[] getEntries() {
117 return mEntries;
118 }
119
120 /**
121 * The array to find the value to save for a preference when an entry from
122 * entries is selected. If a user clicks on the second item in entries, the
123 * second item in this array will be saved to the preference.
124 *
125 * @param entryValues The array to be used as values to save for the preference.
126 */
127 public void setEntryValues(String[] entryValues) {
128 mEntryValues = entryValues;
129 Arrays.fill(mSetValues, false);
130 Arrays.fill(mOrigValues, false);
131 }
132
133 /**
134 * @see #setEntryValues(CharSequence[])
135 * @param entryValuesResId The entry values array as a resource.
136 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700137 public void setEntryValues(@ArrayRes int entryValuesResId) {
Dianne Hackborn7746f912012-04-26 15:34:57 -0700138 setEntryValuesCS(getContext().getResources().getTextArray(entryValuesResId));
139 }
140
141 private void setEntryValuesCS(CharSequence[] values) {
142 setValues(null);
143 if (values != null) {
144 mEntryValues = new String[values.length];
145 for (int i=0; i<values.length; i++) {
146 mEntryValues[i] = values[i].toString();
147 }
148 }
149 }
150
151 /**
152 * Returns the array of values to be saved for the preference.
153 *
154 * @return The array of values.
155 */
Dianne Hackborn83e6eb12012-05-08 14:53:24 -0700156 public String[] getEntryValues() {
Dianne Hackborn7746f912012-04-26 15:34:57 -0700157 return mEntryValues;
158 }
159
160 /**
Dianne Hackborn83e6eb12012-05-08 14:53:24 -0700161 * Get the boolean state of a given value.
162 */
163 public boolean getValue(int index) {
164 return mSetValues[index];
165 }
166
167 /**
168 * Set the boolean state of a given value.
169 */
170 public void setValue(int index, boolean state) {
171 mSetValues[index] = state;
172 }
173
174 /**
Dianne Hackborn7746f912012-04-26 15:34:57 -0700175 * Sets the current values.
176 */
177 public void setValues(boolean[] values) {
178 if (mSetValues != null) {
179 Arrays.fill(mSetValues, false);
180 Arrays.fill(mOrigValues, false);
181 if (values != null) {
182 System.arraycopy(values, 0, mSetValues, 0,
183 values.length < mSetValues.length ? values.length : mSetValues.length);
184 }
185 }
186 }
187
188 /**
189 * Returns the summary of this ListPreference. If the summary
190 * has a {@linkplain java.lang.String#format String formatting}
191 * marker in it (i.e. "%s" or "%1$s"), then the current entry
192 * value will be substituted in its place.
193 *
194 * @return the summary with appropriate string substitution
195 */
196 @Override
197 public CharSequence getSummary() {
198 if (mSummary == null) {
199 return super.getSummary();
200 } else {
201 return mSummary;
202 }
203 }
204
205 /**
206 * Sets the summary for this Preference with a CharSequence.
207 * If the summary has a
208 * {@linkplain java.lang.String#format String formatting}
209 * marker in it (i.e. "%s" or "%1$s"), then the current entry
210 * value will be substituted in its place when it's retrieved.
211 *
212 * @param summary The summary for the preference.
213 */
214 @Override
215 public void setSummary(CharSequence summary) {
216 super.setSummary(summary);
217 if (summary == null && mSummary != null) {
218 mSummary = null;
219 } else if (summary != null && !summary.equals(mSummary)) {
220 mSummary = summary.toString();
221 }
222 }
223
224 /**
225 * Returns the currently selected values.
226 */
227 public boolean[] getValues() {
228 return mSetValues;
229 }
230
231 /**
232 * Returns the index of the given value (in the entry values array).
233 *
234 * @param value The value whose index should be returned.
235 * @return The index of the value, or -1 if not found.
236 */
237 public int findIndexOfValue(String value) {
238 if (value != null && mEntryValues != null) {
239 for (int i = mEntryValues.length - 1; i >= 0; i--) {
240 if (mEntryValues[i].equals(value)) {
241 return i;
242 }
243 }
244 }
245 return -1;
246 }
247
248 @Override
249 protected void onPrepareDialogBuilder(Builder builder) {
250 super.onPrepareDialogBuilder(builder);
251
252 if (mEntries == null || mEntryValues == null) {
253 throw new IllegalStateException(
254 "ListPreference requires an entries array and an entryValues array.");
255 }
256
257 mOrigValues = Arrays.copyOf(mSetValues, mSetValues.length);
258 builder.setMultiChoiceItems(mEntries, mSetValues,
259 new DialogInterface.OnMultiChoiceClickListener() {
260 @Override
261 public void onClick(DialogInterface dialog, int which, boolean isChecked) {
262 mSetValues[which] = isChecked;
263 }
264 });
265 }
266
267 @Override
268 protected void onDialogClosed(boolean positiveResult) {
269 super.onDialogClosed(positiveResult);
270
271 if (positiveResult) {
272 if (callChangeListener(getValues())) {
273 return;
274 }
275 }
276 System.arraycopy(mOrigValues, 0, mSetValues, 0, mSetValues.length);
277 }
278
279 @Override
280 protected Object onGetDefaultValue(TypedArray a, int index) {
281 return a.getString(index);
282 }
283
284 @Override
285 protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
286 }
287
288 @Override
289 protected Parcelable onSaveInstanceState() {
290 final Parcelable superState = super.onSaveInstanceState();
291 if (isPersistent()) {
292 // No need to save instance state since it's persistent
293 return superState;
294 }
295
296 final SavedState myState = new SavedState(superState);
297 myState.values = getValues();
298 return myState;
299 }
300
301 @Override
302 protected void onRestoreInstanceState(Parcelable state) {
303 if (state == null || !state.getClass().equals(SavedState.class)) {
304 // Didn't save state for us in onSaveInstanceState
305 super.onRestoreInstanceState(state);
306 return;
307 }
308
309 SavedState myState = (SavedState) state;
310 super.onRestoreInstanceState(myState.getSuperState());
311 setValues(myState.values);
312 }
313
314 private static class SavedState extends BaseSavedState {
315 boolean[] values;
316
317 public SavedState(Parcel source) {
318 super(source);
319 values = source.createBooleanArray();
320 }
321
322 @Override
323 public void writeToParcel(Parcel dest, int flags) {
324 super.writeToParcel(dest, flags);
325 dest.writeBooleanArray(values);
326 }
327
328 public SavedState(Parcelable superState) {
329 super(superState);
330 }
331
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700332 public static final @android.annotation.NonNull Parcelable.Creator<SavedState> CREATOR =
Dianne Hackborn7746f912012-04-26 15:34:57 -0700333 new Parcelable.Creator<SavedState>() {
334 public SavedState createFromParcel(Parcel in) {
335 return new SavedState(in);
336 }
337
338 public SavedState[] newArray(int size) {
339 return new SavedState[size];
340 }
341 };
342 }
343
344}