Add MultiSelectListPreferenceDialogFragmentCompat
b/28194519
Change-Id: I8c150a52e4e1cde59899c39fc1f2f2faafa5b8ef
diff --git a/api/current.txt b/api/current.txt
index 6023b60..7647e0d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8511,6 +8511,12 @@
method public void onDialogClosed(boolean);
}
+ public class MultiSelectListPreferenceDialogFragmentCompat extends android.support.v7.preference.PreferenceDialogFragmentCompat {
+ ctor public MultiSelectListPreferenceDialogFragmentCompat();
+ method public static android.support.v7.preference.MultiSelectListPreferenceDialogFragmentCompat newInstance(java.lang.String);
+ method public void onDialogClosed(boolean);
+ }
+
public class Preference implements java.lang.Comparable {
ctor public Preference(android.content.Context, android.util.AttributeSet, int, int);
ctor public Preference(android.content.Context, android.util.AttributeSet, int);
diff --git a/samples/SupportPreferenceDemos/res/values/strings.xml b/samples/SupportPreferenceDemos/res/values/strings.xml
index 219808d..93f09c3 100644
--- a/samples/SupportPreferenceDemos/res/values/strings.xml
+++ b/samples/SupportPreferenceDemos/res/values/strings.xml
@@ -46,6 +46,10 @@
<string name="summary_list_preference">An example that uses a list dialog</string>
<string name="dialog_title_list_preference">Choose one</string>
+ <string name="title_multi_list_preference">Multi-select list preference</string>
+ <string name="summary_multi_list_preference">An example that uses a multi-select list dialog</string>
+ <string name="dialog_title_multi_list_preference">Choose some</string>
+
<string name="title_screen_preference">Screen preference</string>
<string name="summary_screen_preference">Shows another screen of preferences</string>
diff --git a/samples/SupportPreferenceDemos/res/xml/preferences.xml b/samples/SupportPreferenceDemos/res/xml/preferences.xml
index 5aa72d3..fecea4f 100644
--- a/samples/SupportPreferenceDemos/res/xml/preferences.xml
+++ b/samples/SupportPreferenceDemos/res/xml/preferences.xml
@@ -48,6 +48,14 @@
android:entryValues="@array/entryvalues_list_preference"
android:dialogTitle="@string/dialog_title_list_preference" />
+ <MultiSelectListPreference
+ android:key="multi_select_list_preference"
+ android:title="@string/title_multi_list_preference"
+ android:summary="@string/summary_multi_list_preference"
+ android:entries="@array/entries_list_preference"
+ android:entryValues="@array/entryvalues_list_preference"
+ android:dialogTitle="@string/dialog_title_multi_list_preference" />
+
</PreferenceCategory>
<PreferenceCategory
diff --git a/v14/preference/src/android/support/v14/preference/MultiSelectListPreference.java b/v14/preference/src/android/support/v14/preference/MultiSelectListPreference.java
index 82b3ad9..cb3ebc3 100644
--- a/v14/preference/src/android/support/v14/preference/MultiSelectListPreference.java
+++ b/v14/preference/src/android/support/v14/preference/MultiSelectListPreference.java
@@ -25,7 +25,7 @@
import android.support.annotation.NonNull;
import android.support.v4.content.SharedPreferencesCompat;
import android.support.v4.content.res.TypedArrayUtils;
-import android.support.v7.preference.DialogPreference;
+import android.support.v7.preference.internal.AbstractMultiSelectListPreference;
import android.util.AttributeSet;
import java.util.Collections;
@@ -43,7 +43,7 @@
* @attr name android:entries
* @attr name android:entryValues
*/
-public class MultiSelectListPreference extends DialogPreference {
+public class MultiSelectListPreference extends AbstractMultiSelectListPreference {
private CharSequence[] mEntries;
private CharSequence[] mEntryValues;
private Set<String> mValues = new HashSet<>();
diff --git a/v14/preference/src/android/support/v14/preference/MultiSelectListPreferenceDialogFragment.java b/v14/preference/src/android/support/v14/preference/MultiSelectListPreferenceDialogFragment.java
index 5b585bc..6f116db 100644
--- a/v14/preference/src/android/support/v14/preference/MultiSelectListPreferenceDialogFragment.java
+++ b/v14/preference/src/android/support/v14/preference/MultiSelectListPreferenceDialogFragment.java
@@ -20,6 +20,7 @@
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
+import android.support.v7.preference.internal.AbstractMultiSelectListPreference;
import java.util.ArrayList;
import java.util.HashSet;
@@ -55,7 +56,7 @@
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
- final MultiSelectListPreference preference = getListPreference();
+ final AbstractMultiSelectListPreference preference = getListPreference();
if (preference.getEntries() == null || preference.getEntryValues() == null) {
throw new IllegalStateException(
@@ -86,8 +87,8 @@
outState.putCharSequenceArray(SAVE_STATE_ENTRY_VALUES, mEntryValues);
}
- private MultiSelectListPreference getListPreference() {
- return (MultiSelectListPreference) getPreference();
+ private AbstractMultiSelectListPreference getListPreference() {
+ return (AbstractMultiSelectListPreference) getPreference();
}
@Override
@@ -115,7 +116,7 @@
@Override
public void onDialogClosed(boolean positiveResult) {
- final MultiSelectListPreference preference = getListPreference();
+ final AbstractMultiSelectListPreference preference = getListPreference();
if (positiveResult && mPreferenceChanged) {
final Set<String> values = mNewValues;
if (preference.callChangeListener(values)) {
@@ -124,5 +125,4 @@
}
mPreferenceChanged = false;
}
-
}
diff --git a/v7/preference/src/android/support/v7/preference/MultiSelectListPreferenceDialogFragmentCompat.java b/v7/preference/src/android/support/v7/preference/MultiSelectListPreferenceDialogFragmentCompat.java
new file mode 100644
index 0000000..370c960
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/MultiSelectListPreferenceDialogFragmentCompat.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.support.v7.preference;
+
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.preference.internal.AbstractMultiSelectListPreference;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+public class MultiSelectListPreferenceDialogFragmentCompat extends PreferenceDialogFragmentCompat {
+
+ private static final String SAVE_STATE_VALUES =
+ "MultiSelectListPreferenceDialogFragmentCompat.values";
+ private static final String SAVE_STATE_CHANGED =
+ "MultiSelectListPreferenceDialogFragmentCompat.changed";
+ private static final String SAVE_STATE_ENTRIES =
+ "MultiSelectListPreferenceDialogFragmentCompat.entries";
+ private static final String SAVE_STATE_ENTRY_VALUES =
+ "MultiSelectListPreferenceDialogFragmentCompat.entryValues";
+
+ private Set<String> mNewValues = new HashSet<>();
+ private boolean mPreferenceChanged;
+ private CharSequence[] mEntries;
+ private CharSequence[] mEntryValues;
+
+ public static MultiSelectListPreferenceDialogFragmentCompat newInstance(String key) {
+ final MultiSelectListPreferenceDialogFragmentCompat fragment =
+ new MultiSelectListPreferenceDialogFragmentCompat();
+ final Bundle b = new Bundle(1);
+ b.putString(ARG_KEY, key);
+ fragment.setArguments(b);
+ return fragment;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (savedInstanceState == null) {
+ final AbstractMultiSelectListPreference preference = getListPreference();
+
+ if (preference.getEntries() == null || preference.getEntryValues() == null) {
+ throw new IllegalStateException(
+ "MultiSelectListPreference requires an entries array and " +
+ "an entryValues array.");
+ }
+
+ mNewValues.clear();
+ mNewValues.addAll(preference.getValues());
+ mPreferenceChanged = false;
+ mEntries = preference.getEntries();
+ mEntryValues = preference.getEntryValues();
+ } else {
+ mNewValues.clear();
+ mNewValues.addAll(savedInstanceState.getStringArrayList(SAVE_STATE_VALUES));
+ mPreferenceChanged = savedInstanceState.getBoolean(SAVE_STATE_CHANGED, false);
+ mEntries = savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRIES);
+ mEntryValues = savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRY_VALUES);
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(@NonNull Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putStringArrayList(SAVE_STATE_VALUES, new ArrayList<>(mNewValues));
+ outState.putBoolean(SAVE_STATE_CHANGED, mPreferenceChanged);
+ outState.putCharSequenceArray(SAVE_STATE_ENTRIES, mEntries);
+ outState.putCharSequenceArray(SAVE_STATE_ENTRY_VALUES, mEntryValues);
+ }
+
+ private AbstractMultiSelectListPreference getListPreference() {
+ return (AbstractMultiSelectListPreference) getPreference();
+ }
+
+ @Override
+ protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
+ super.onPrepareDialogBuilder(builder);
+
+ final int entryCount = mEntryValues.length;
+ final boolean[] checkedItems = new boolean[entryCount];
+ for (int i = 0; i < entryCount; i++) {
+ checkedItems[i] = mNewValues.contains(mEntryValues[i].toString());
+ }
+ builder.setMultiChoiceItems(mEntries, checkedItems,
+ new DialogInterface.OnMultiChoiceClickListener() {
+ public void onClick(DialogInterface dialog, int which, boolean isChecked) {
+ if (isChecked) {
+ mPreferenceChanged |= mNewValues.add(
+ mEntryValues[which].toString());
+ } else {
+ mPreferenceChanged |= mNewValues.remove(
+ mEntryValues[which].toString());
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onDialogClosed(boolean positiveResult) {
+ final AbstractMultiSelectListPreference preference = getListPreference();
+ if (positiveResult && mPreferenceChanged) {
+ final Set<String> values = mNewValues;
+ if (preference.callChangeListener(values)) {
+ preference.setValues(values);
+ }
+ }
+ mPreferenceChanged = false;
+ }
+}
diff --git a/v7/preference/src/android/support/v7/preference/PreferenceFragmentCompat.java b/v7/preference/src/android/support/v7/preference/PreferenceFragmentCompat.java
index 5c093e8..527138b 100644
--- a/v7/preference/src/android/support/v7/preference/PreferenceFragmentCompat.java
+++ b/v7/preference/src/android/support/v7/preference/PreferenceFragmentCompat.java
@@ -29,6 +29,7 @@
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewCompat;
+import android.support.v7.preference.internal.AbstractMultiSelectListPreference;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.TypedValue;
@@ -631,6 +632,8 @@
f = EditTextPreferenceDialogFragmentCompat.newInstance(preference.getKey());
} else if (preference instanceof ListPreference) {
f = ListPreferenceDialogFragmentCompat.newInstance(preference.getKey());
+ } else if (preference instanceof AbstractMultiSelectListPreference) {
+ f = MultiSelectListPreferenceDialogFragmentCompat.newInstance(preference.getKey());
} else {
throw new IllegalArgumentException("Tried to display dialog for unknown " +
"preference type. Did you forget to override onDisplayPreferenceDialog()?");
diff --git a/v7/preference/src/android/support/v7/preference/internal/AbstractMultiSelectListPreference.java b/v7/preference/src/android/support/v7/preference/internal/AbstractMultiSelectListPreference.java
new file mode 100644
index 0000000..737c209
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/internal/AbstractMultiSelectListPreference.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.support.v7.preference.internal;
+
+import android.content.Context;
+import android.support.v7.preference.DialogPreference;
+import android.util.AttributeSet;
+
+import java.util.Set;
+
+/**
+ * Stub superclass for {@link android.support.v14.preference.MultiSelectListPreference} so that we
+ * can reference it from
+ * {@link android.support.v7.preference.MultiSelectListPreferenceDialogFragmentCompat}
+ *
+ * @hide
+ */
+public abstract class AbstractMultiSelectListPreference extends DialogPreference {
+ public AbstractMultiSelectListPreference(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ public AbstractMultiSelectListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public AbstractMultiSelectListPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public AbstractMultiSelectListPreference(Context context) {
+ super(context);
+ }
+
+ public abstract CharSequence[] getEntries();
+ public abstract Set<String> getValues();
+ public abstract CharSequence[] getEntryValues();
+ public abstract void setValues(Set<String> values);
+}