blob: 43182d9ebbdd45e2e149e2b52e94f262b17ccaf2 [file] [log] [blame]
Adam Powell212db7d2010-04-08 16:24:46 -07001/*
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.ArrayRes;
Adam Powell212db7d2010-04-08 16:24:46 -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
28import java.util.HashSet;
29import java.util.Set;
30
31/**
32 * A {@link Preference} that displays a list of entries as
33 * a dialog.
34 * <p>
35 * This preference will store a set of strings into the SharedPreferences.
36 * This set will contain one or more values from the
37 * {@link #setEntryValues(CharSequence[])} array.
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +000038 *
Adam Powell212db7d2010-04-08 16:24:46 -070039 * @attr ref android.R.styleable#MultiSelectListPreference_entries
40 * @attr ref android.R.styleable#MultiSelectListPreference_entryValues
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +000041 *
42 * @deprecated Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
43 * <a href="{@docRoot}reference/androidx/preference/package-summary.html">
44 * Preference Library</a> for consistent behavior across all devices. For more information on
45 * using the AndroidX Preference Library see
46 * <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a>.
Adam Powell212db7d2010-04-08 16:24:46 -070047 */
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +000048@Deprecated
Adam Powell212db7d2010-04-08 16:24:46 -070049public class MultiSelectListPreference extends DialogPreference {
50 private CharSequence[] mEntries;
51 private CharSequence[] mEntryValues;
52 private Set<String> mValues = new HashSet<String>();
53 private Set<String> mNewValues = new HashSet<String>();
54 private boolean mPreferenceChanged;
Alan Viverette617feb92013-09-09 18:09:13 -070055
56 public MultiSelectListPreference(
57 Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
58 super(context, attrs, defStyleAttr, defStyleRes);
59
60 final TypedArray a = context.obtainStyledAttributes(attrs,
61 com.android.internal.R.styleable.MultiSelectListPreference, defStyleAttr,
62 defStyleRes);
Adam Powell212db7d2010-04-08 16:24:46 -070063 mEntries = a.getTextArray(com.android.internal.R.styleable.MultiSelectListPreference_entries);
64 mEntryValues = a.getTextArray(com.android.internal.R.styleable.MultiSelectListPreference_entryValues);
65 a.recycle();
66 }
Alan Viverette617feb92013-09-09 18:09:13 -070067
68 public MultiSelectListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
69 this(context, attrs, defStyleAttr, 0);
70 }
71
72 public MultiSelectListPreference(Context context, AttributeSet attrs) {
Alan Viverette599d2a42013-09-16 13:48:29 -070073 this(context, attrs, com.android.internal.R.attr.dialogPreferenceStyle);
Alan Viverette617feb92013-09-09 18:09:13 -070074 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +000075
Adam Powell212db7d2010-04-08 16:24:46 -070076 public MultiSelectListPreference(Context context) {
77 this(context, null);
78 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +000079
Adam Powell212db7d2010-04-08 16:24:46 -070080 /**
81 * Sets the human-readable entries to be shown in the list. This will be
82 * shown in subsequent dialogs.
83 * <p>
84 * Each entry must have a corresponding index in
85 * {@link #setEntryValues(CharSequence[])}.
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +000086 *
Adam Powell212db7d2010-04-08 16:24:46 -070087 * @param entries The entries.
88 * @see #setEntryValues(CharSequence[])
89 */
90 public void setEntries(CharSequence[] entries) {
91 mEntries = entries;
92 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +000093
Adam Powell212db7d2010-04-08 16:24:46 -070094 /**
95 * @see #setEntries(CharSequence[])
96 * @param entriesResId The entries array as a resource.
97 */
Tor Norbye7b9c9122013-05-30 16:48:33 -070098 public void setEntries(@ArrayRes int entriesResId) {
Adam Powell212db7d2010-04-08 16:24:46 -070099 setEntries(getContext().getResources().getTextArray(entriesResId));
100 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000101
Adam Powell212db7d2010-04-08 16:24:46 -0700102 /**
103 * The list of entries to be shown in the list in subsequent dialogs.
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000104 *
Adam Powell212db7d2010-04-08 16:24:46 -0700105 * @return The list as an array.
106 */
107 public CharSequence[] getEntries() {
108 return mEntries;
109 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000110
Adam Powell212db7d2010-04-08 16:24:46 -0700111 /**
112 * The array to find the value to save for a preference when an entry from
113 * entries is selected. If a user clicks on the second item in entries, the
114 * second item in this array will be saved to the preference.
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000115 *
Adam Powell212db7d2010-04-08 16:24:46 -0700116 * @param entryValues The array to be used as values to save for the preference.
117 */
118 public void setEntryValues(CharSequence[] entryValues) {
119 mEntryValues = entryValues;
120 }
121
122 /**
123 * @see #setEntryValues(CharSequence[])
124 * @param entryValuesResId The entry values array as a resource.
125 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700126 public void setEntryValues(@ArrayRes int entryValuesResId) {
Adam Powell212db7d2010-04-08 16:24:46 -0700127 setEntryValues(getContext().getResources().getTextArray(entryValuesResId));
128 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000129
Adam Powell212db7d2010-04-08 16:24:46 -0700130 /**
131 * Returns the array of values to be saved for the preference.
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000132 *
Adam Powell212db7d2010-04-08 16:24:46 -0700133 * @return The array of values.
134 */
135 public CharSequence[] getEntryValues() {
136 return mEntryValues;
137 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000138
Adam Powell212db7d2010-04-08 16:24:46 -0700139 /**
140 * Sets the value of the key. This should contain entries in
141 * {@link #getEntryValues()}.
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000142 *
Adam Powell212db7d2010-04-08 16:24:46 -0700143 * @param values The values to set for the key.
144 */
145 public void setValues(Set<String> values) {
Amith Yamasanicd9ea082012-05-15 17:17:24 -0700146 mValues.clear();
147 mValues.addAll(values);
148
Adam Powell212db7d2010-04-08 16:24:46 -0700149 persistStringSet(values);
150 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000151
Adam Powell212db7d2010-04-08 16:24:46 -0700152 /**
153 * Retrieves the current value of the key.
154 */
155 public Set<String> getValues() {
156 return mValues;
157 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000158
Adam Powell212db7d2010-04-08 16:24:46 -0700159 /**
160 * Returns the index of the given value (in the entry values array).
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000161 *
Adam Powell212db7d2010-04-08 16:24:46 -0700162 * @param value The value whose index should be returned.
163 * @return The index of the value, or -1 if not found.
164 */
165 public int findIndexOfValue(String value) {
166 if (value != null && mEntryValues != null) {
167 for (int i = mEntryValues.length - 1; i >= 0; i--) {
168 if (mEntryValues[i].equals(value)) {
169 return i;
170 }
171 }
172 }
173 return -1;
174 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000175
Adam Powell212db7d2010-04-08 16:24:46 -0700176 @Override
177 protected void onPrepareDialogBuilder(Builder builder) {
178 super.onPrepareDialogBuilder(builder);
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000179
Adam Powell212db7d2010-04-08 16:24:46 -0700180 if (mEntries == null || mEntryValues == null) {
181 throw new IllegalStateException(
182 "MultiSelectListPreference requires an entries array and " +
183 "an entryValues array.");
184 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000185
Adam Powell212db7d2010-04-08 16:24:46 -0700186 boolean[] checkedItems = getSelectedItems();
187 builder.setMultiChoiceItems(mEntries, checkedItems,
188 new DialogInterface.OnMultiChoiceClickListener() {
189 public void onClick(DialogInterface dialog, int which, boolean isChecked) {
190 if (isChecked) {
Justin Kohece60fb2011-04-07 19:40:29 -0700191 mPreferenceChanged |= mNewValues.add(mEntryValues[which].toString());
Adam Powell212db7d2010-04-08 16:24:46 -0700192 } else {
Justin Kohece60fb2011-04-07 19:40:29 -0700193 mPreferenceChanged |= mNewValues.remove(mEntryValues[which].toString());
Adam Powell212db7d2010-04-08 16:24:46 -0700194 }
195 }
196 });
197 mNewValues.clear();
198 mNewValues.addAll(mValues);
199 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000200
Adam Powell212db7d2010-04-08 16:24:46 -0700201 private boolean[] getSelectedItems() {
Justin Kohece60fb2011-04-07 19:40:29 -0700202 final CharSequence[] entries = mEntryValues;
Adam Powell212db7d2010-04-08 16:24:46 -0700203 final int entryCount = entries.length;
204 final Set<String> values = mValues;
205 boolean[] result = new boolean[entryCount];
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000206
Adam Powell212db7d2010-04-08 16:24:46 -0700207 for (int i = 0; i < entryCount; i++) {
208 result[i] = values.contains(entries[i].toString());
209 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000210
Adam Powell212db7d2010-04-08 16:24:46 -0700211 return result;
212 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000213
Adam Powell212db7d2010-04-08 16:24:46 -0700214 @Override
215 protected void onDialogClosed(boolean positiveResult) {
216 super.onDialogClosed(positiveResult);
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000217
Adam Powell212db7d2010-04-08 16:24:46 -0700218 if (positiveResult && mPreferenceChanged) {
219 final Set<String> values = mNewValues;
220 if (callChangeListener(values)) {
221 setValues(values);
222 }
223 }
224 mPreferenceChanged = false;
225 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000226
Adam Powell212db7d2010-04-08 16:24:46 -0700227 @Override
228 protected Object onGetDefaultValue(TypedArray a, int index) {
229 final CharSequence[] defaultValues = a.getTextArray(index);
230 final int valueCount = defaultValues.length;
231 final Set<String> result = new HashSet<String>();
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000232
Adam Powell212db7d2010-04-08 16:24:46 -0700233 for (int i = 0; i < valueCount; i++) {
234 result.add(defaultValues[i].toString());
235 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000236
Adam Powell212db7d2010-04-08 16:24:46 -0700237 return result;
238 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000239
Adam Powell212db7d2010-04-08 16:24:46 -0700240 @Override
241 protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
242 setValues(restoreValue ? getPersistedStringSet(mValues) : (Set<String>) defaultValue);
243 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000244
Adam Powell212db7d2010-04-08 16:24:46 -0700245 @Override
246 protected Parcelable onSaveInstanceState() {
247 final Parcelable superState = super.onSaveInstanceState();
248 if (isPersistent()) {
249 // No need to save instance state
250 return superState;
251 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000252
Adam Powell212db7d2010-04-08 16:24:46 -0700253 final SavedState myState = new SavedState(superState);
254 myState.values = getValues();
255 return myState;
256 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000257
Adam Powell212db7d2010-04-08 16:24:46 -0700258 private static class SavedState extends BaseSavedState {
259 Set<String> values;
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000260
Adam Powell212db7d2010-04-08 16:24:46 -0700261 public SavedState(Parcel source) {
262 super(source);
263 values = new HashSet<String>();
264 String[] strings = source.readStringArray();
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000265
Adam Powell212db7d2010-04-08 16:24:46 -0700266 final int stringCount = strings.length;
267 for (int i = 0; i < stringCount; i++) {
268 values.add(strings[i]);
269 }
270 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000271
Adam Powell212db7d2010-04-08 16:24:46 -0700272 public SavedState(Parcelable superState) {
273 super(superState);
274 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000275
Adam Powell212db7d2010-04-08 16:24:46 -0700276 @Override
277 public void writeToParcel(Parcel dest, int flags) {
278 super.writeToParcel(dest, flags);
279 dest.writeStringArray(values.toArray(new String[0]));
280 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000281
Adam Powell212db7d2010-04-08 16:24:46 -0700282 public static final Parcelable.Creator<SavedState> CREATOR =
283 new Parcelable.Creator<SavedState>() {
284 public SavedState createFromParcel(Parcel in) {
285 return new SavedState(in);
286 }
Louis Pullen-Freilichb9596fa2018-11-19 17:40:56 +0000287
Adam Powell212db7d2010-04-08 16:24:46 -0700288 public SavedState[] newArray(int size) {
289 return new SavedState[size];
290 }
291 };
292 }
293}