1 /* 2 * Copyright (C) 2015 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 android.support.v7.preference; 18 19 import android.content.DialogInterface; 20 import android.os.Bundle; 21 import android.support.annotation.NonNull; 22 import android.support.v7.app.AlertDialog; 23 24 import java.util.ArrayList; 25 26 public class ListPreferenceDialogFragmentCompat extends PreferenceDialogFragmentCompat { 27 28 private static final String SAVE_STATE_INDEX = "ListPreferenceDialogFragment.index"; 29 private static final String SAVE_STATE_ENTRIES = "ListPreferenceDialogFragment.entries"; 30 private static final String SAVE_STATE_ENTRY_VALUES = 31 "ListPreferenceDialogFragment.entryValues"; 32 33 private int mClickedDialogEntryIndex; 34 private CharSequence[] mEntries; 35 private CharSequence[] mEntryValues; 36 newInstance(String key)37 public static ListPreferenceDialogFragmentCompat newInstance(String key) { 38 final ListPreferenceDialogFragmentCompat fragment = 39 new ListPreferenceDialogFragmentCompat(); 40 final Bundle b = new Bundle(1); 41 b.putString(ARG_KEY, key); 42 fragment.setArguments(b); 43 return fragment; 44 } 45 46 @Override onCreate(Bundle savedInstanceState)47 public void onCreate(Bundle savedInstanceState) { 48 super.onCreate(savedInstanceState); 49 if (savedInstanceState == null) { 50 final ListPreference preference = getListPreference(); 51 52 if (preference.getEntries() == null || preference.getEntryValues() == null) { 53 throw new IllegalStateException( 54 "ListPreference requires an entries array and an entryValues array."); 55 } 56 57 mClickedDialogEntryIndex = preference.findIndexOfValue(preference.getValue()); 58 mEntries = preference.getEntries(); 59 mEntryValues = preference.getEntryValues(); 60 } else { 61 mClickedDialogEntryIndex = savedInstanceState.getInt(SAVE_STATE_INDEX, 0); 62 mEntries = getCharSequenceArray(savedInstanceState, SAVE_STATE_ENTRIES); 63 mEntryValues = getCharSequenceArray(savedInstanceState, SAVE_STATE_ENTRY_VALUES); 64 } 65 } 66 67 @Override onSaveInstanceState(@onNull Bundle outState)68 public void onSaveInstanceState(@NonNull Bundle outState) { 69 super.onSaveInstanceState(outState); 70 outState.putInt(SAVE_STATE_INDEX, mClickedDialogEntryIndex); 71 putCharSequenceArray(outState, SAVE_STATE_ENTRIES, mEntries); 72 putCharSequenceArray(outState, SAVE_STATE_ENTRY_VALUES, mEntryValues); 73 } 74 putCharSequenceArray(Bundle out, String key, CharSequence[] entries)75 private static void putCharSequenceArray(Bundle out, String key, CharSequence[] entries) { 76 final ArrayList<String> stored = new ArrayList<>(entries.length); 77 78 for (final CharSequence cs : entries) { 79 stored.add(cs.toString()); 80 } 81 82 out.putStringArrayList(key, stored); 83 } 84 getCharSequenceArray(Bundle in, String key)85 private static CharSequence[] getCharSequenceArray(Bundle in, String key) { 86 final ArrayList<String> stored = in.getStringArrayList(key); 87 88 return stored == null ? null : stored.toArray(new CharSequence[stored.size()]); 89 } 90 getListPreference()91 private ListPreference getListPreference() { 92 return (ListPreference) getPreference(); 93 } 94 95 @Override onPrepareDialogBuilder(AlertDialog.Builder builder)96 protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { 97 super.onPrepareDialogBuilder(builder); 98 99 builder.setSingleChoiceItems(mEntries, mClickedDialogEntryIndex, 100 new DialogInterface.OnClickListener() { 101 @Override 102 public void onClick(DialogInterface dialog, int which) { 103 mClickedDialogEntryIndex = which; 104 105 /* 106 * Clicking on an item simulates the positive button 107 * click, and dismisses the dialog. 108 */ 109 ListPreferenceDialogFragmentCompat.this.onClick(dialog, 110 DialogInterface.BUTTON_POSITIVE); 111 dialog.dismiss(); 112 } 113 }); 114 115 /* 116 * The typical interaction for list-based dialogs is to have 117 * click-on-an-item dismiss the dialog instead of the user having to 118 * press 'Ok'. 119 */ 120 builder.setPositiveButton(null, null); 121 } 122 123 @Override onDialogClosed(boolean positiveResult)124 public void onDialogClosed(boolean positiveResult) { 125 final ListPreference preference = getListPreference(); 126 if (positiveResult && mClickedDialogEntryIndex >= 0) { 127 String value = mEntryValues[mClickedDialogEntryIndex].toString(); 128 if (preference.callChangeListener(value)) { 129 preference.setValue(value); 130 } 131 } 132 } 133 134 } 135