Home | History | Annotate | Download | only in preference
      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 
     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
     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
     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 
     91     private AbstractMultiSelectListPreference getListPreference() {
     92         return (AbstractMultiSelectListPreference) getPreference();
     93     }
     94 
     95     @Override
     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
    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