• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 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 
17 package androidx.preference;
18 
19 import android.content.DialogInterface;
20 import android.os.Bundle;
21 
22 import androidx.annotation.NonNull;
23 import androidx.appcompat.app.AlertDialog;
24 import androidx.preference.internal.AbstractMultiSelectListPreference;
25 
26 import java.util.ArrayList;
27 import java.util.HashSet;
28 import java.util.Set;
29 
30 public class MultiSelectListPreferenceDialogFragmentCompat extends PreferenceDialogFragmentCompat {
31 
32     private static final String SAVE_STATE_VALUES =
33             "MultiSelectListPreferenceDialogFragmentCompat.values";
34     private static final String SAVE_STATE_CHANGED =
35             "MultiSelectListPreferenceDialogFragmentCompat.changed";
36     private static final String SAVE_STATE_ENTRIES =
37             "MultiSelectListPreferenceDialogFragmentCompat.entries";
38     private static final String SAVE_STATE_ENTRY_VALUES =
39             "MultiSelectListPreferenceDialogFragmentCompat.entryValues";
40 
41     private Set<String> mNewValues = new HashSet<>();
42     private boolean mPreferenceChanged;
43     private CharSequence[] mEntries;
44     private CharSequence[] mEntryValues;
45 
newInstance(String key)46     public static MultiSelectListPreferenceDialogFragmentCompat newInstance(String key) {
47         final MultiSelectListPreferenceDialogFragmentCompat fragment =
48                 new MultiSelectListPreferenceDialogFragmentCompat();
49         final Bundle b = new Bundle(1);
50         b.putString(ARG_KEY, key);
51         fragment.setArguments(b);
52         return fragment;
53     }
54 
55     @Override
onCreate(Bundle savedInstanceState)56     public void onCreate(Bundle savedInstanceState) {
57         super.onCreate(savedInstanceState);
58 
59         if (savedInstanceState == null) {
60             final AbstractMultiSelectListPreference preference = getListPreference();
61 
62             if (preference.getEntries() == null || preference.getEntryValues() == null) {
63                 throw new IllegalStateException(
64                         "MultiSelectListPreference requires an entries array and " +
65                                 "an entryValues array.");
66             }
67 
68             mNewValues.clear();
69             mNewValues.addAll(preference.getValues());
70             mPreferenceChanged = false;
71             mEntries = preference.getEntries();
72             mEntryValues = preference.getEntryValues();
73         } else {
74             mNewValues.clear();
75             mNewValues.addAll(savedInstanceState.getStringArrayList(SAVE_STATE_VALUES));
76             mPreferenceChanged = savedInstanceState.getBoolean(SAVE_STATE_CHANGED, false);
77             mEntries = savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRIES);
78             mEntryValues = savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRY_VALUES);
79         }
80     }
81 
82     @Override
onSaveInstanceState(@onNull Bundle outState)83     public void onSaveInstanceState(@NonNull Bundle outState) {
84         super.onSaveInstanceState(outState);
85         outState.putStringArrayList(SAVE_STATE_VALUES, new ArrayList<>(mNewValues));
86         outState.putBoolean(SAVE_STATE_CHANGED, mPreferenceChanged);
87         outState.putCharSequenceArray(SAVE_STATE_ENTRIES, mEntries);
88         outState.putCharSequenceArray(SAVE_STATE_ENTRY_VALUES, mEntryValues);
89     }
90 
getListPreference()91     private AbstractMultiSelectListPreference getListPreference() {
92         return (AbstractMultiSelectListPreference) getPreference();
93     }
94 
95     @Override
onPrepareDialogBuilder(AlertDialog.Builder builder)96     protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
97         super.onPrepareDialogBuilder(builder);
98 
99         final int entryCount = mEntryValues.length;
100         final boolean[] checkedItems = new boolean[entryCount];
101         for (int i = 0; i < entryCount; i++) {
102             checkedItems[i] = mNewValues.contains(mEntryValues[i].toString());
103         }
104         builder.setMultiChoiceItems(mEntries, checkedItems,
105                 new DialogInterface.OnMultiChoiceClickListener() {
106                     @Override
107                     public void onClick(DialogInterface dialog, int which, boolean isChecked) {
108                         if (isChecked) {
109                             mPreferenceChanged |= mNewValues.add(
110                                     mEntryValues[which].toString());
111                         } else {
112                             mPreferenceChanged |= mNewValues.remove(
113                                     mEntryValues[which].toString());
114                         }
115                     }
116                 });
117     }
118 
119     @Override
onDialogClosed(boolean positiveResult)120     public void onDialogClosed(boolean positiveResult) {
121         final AbstractMultiSelectListPreference preference = getListPreference();
122         if (positiveResult && mPreferenceChanged) {
123             final Set<String> values = mNewValues;
124             if (preference.callChangeListener(values)) {
125                 preference.setValues(values);
126             }
127         }
128         mPreferenceChanged = false;
129     }
130 }
131