Merge "Stash dialog info when constructing pref dialogs" into mnc-ub-dev am: 30cf890c76
am: 1870114cf6
* commit '1870114cf6c25748ab66dace4e639c812f43d875':
Stash dialog info when constructing pref dialogs
diff --git a/v14/preference/src/android/support/v14/preference/EditTextPreferenceDialogFragment.java b/v14/preference/src/android/support/v14/preference/EditTextPreferenceDialogFragment.java
index 498b874..4f64876 100644
--- a/v14/preference/src/android/support/v14/preference/EditTextPreferenceDialogFragment.java
+++ b/v14/preference/src/android/support/v14/preference/EditTextPreferenceDialogFragment.java
@@ -17,14 +17,19 @@
package android.support.v14.preference;
import android.os.Bundle;
+import android.support.annotation.NonNull;
import android.support.v7.preference.EditTextPreference;
import android.view.View;
import android.widget.EditText;
public class EditTextPreferenceDialogFragment extends PreferenceDialogFragment {
+ private static final String SAVE_STATE_TEXT = "EditTextPreferenceDialogFragment.text";
+
private EditText mEditText;
+ private CharSequence mText;
+
public static EditTextPreferenceDialogFragment newInstance(String key) {
final EditTextPreferenceDialogFragment
fragment = new EditTextPreferenceDialogFragment();
@@ -35,6 +40,22 @@
}
@Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (savedInstanceState == null) {
+ mText = getEditTextPreference().getText();
+ } else {
+ mText = savedInstanceState.getCharSequence(SAVE_STATE_TEXT);
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(@NonNull Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putCharSequence(SAVE_STATE_TEXT, mText);
+ }
+
+ @Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
@@ -45,7 +66,7 @@
" @android:id/edit");
}
- mEditText.setText(getEditTextPreference().getText());
+ mEditText.setText(mText);
}
private EditTextPreference getEditTextPreference() {
diff --git a/v14/preference/src/android/support/v14/preference/ListPreferenceDialogFragment.java b/v14/preference/src/android/support/v14/preference/ListPreferenceDialogFragment.java
index c4e922c..6b385d8 100644
--- a/v14/preference/src/android/support/v14/preference/ListPreferenceDialogFragment.java
+++ b/v14/preference/src/android/support/v14/preference/ListPreferenceDialogFragment.java
@@ -19,11 +19,19 @@
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
+import android.support.annotation.NonNull;
import android.support.v7.preference.ListPreference;
public class ListPreferenceDialogFragment extends PreferenceDialogFragment {
+ private static final String SAVE_STATE_INDEX = "ListPreferenceDialogFragment.index";
+ private static final String SAVE_STATE_ENTRIES = "ListPreferenceDialogFragment.entries";
+ private static final String SAVE_STATE_ENTRY_VALUES =
+ "ListPreferenceDialogFragment.entryValues";
+
private int mClickedDialogEntryIndex;
+ private CharSequence[] mEntries;
+ private CharSequence[] mEntryValues;
public static ListPreferenceDialogFragment newInstance(String key) {
final ListPreferenceDialogFragment fragment = new ListPreferenceDialogFragment();
@@ -33,6 +41,35 @@
return fragment;
}
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (savedInstanceState == null) {
+ final ListPreference preference = getListPreference();
+
+ if (preference.getEntries() == null || preference.getEntryValues() == null) {
+ throw new IllegalStateException(
+ "ListPreference requires an entries array and an entryValues array.");
+ }
+
+ mClickedDialogEntryIndex = preference.findIndexOfValue(preference.getValue());
+ mEntries = preference.getEntries();
+ mEntryValues = preference.getEntryValues();
+ } else {
+ mClickedDialogEntryIndex = savedInstanceState.getInt(SAVE_STATE_INDEX, 0);
+ mEntries = savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRIES);
+ mEntryValues = savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRY_VALUES);
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(@NonNull Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putInt(SAVE_STATE_INDEX, mClickedDialogEntryIndex);
+ outState.putCharSequenceArray(SAVE_STATE_ENTRIES, mEntries);
+ outState.putCharSequenceArray(SAVE_STATE_ENTRY_VALUES, mEntryValues);
+ }
+
private ListPreference getListPreference() {
return (ListPreference) getPreference();
}
@@ -41,15 +78,7 @@
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
super.onPrepareDialogBuilder(builder);
- final ListPreference preference = getListPreference();
-
- if (preference.getEntries() == null || preference.getEntryValues() == null) {
- throw new IllegalStateException(
- "ListPreference requires an entries array and an entryValues array.");
- }
-
- mClickedDialogEntryIndex = preference.findIndexOfValue(preference.getValue());
- builder.setSingleChoiceItems(preference.getEntries(), mClickedDialogEntryIndex,
+ builder.setSingleChoiceItems(mEntries, mClickedDialogEntryIndex,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mClickedDialogEntryIndex = which;
@@ -75,9 +104,8 @@
@Override
public void onDialogClosed(boolean positiveResult) {
final ListPreference preference = getListPreference();
- if (positiveResult && mClickedDialogEntryIndex >= 0 &&
- preference.getEntryValues() != null) {
- String value = preference.getEntryValues()[mClickedDialogEntryIndex].toString();
+ if (positiveResult && mClickedDialogEntryIndex >= 0) {
+ String value = mEntryValues[mClickedDialogEntryIndex].toString();
if (preference.callChangeListener(value)) {
preference.setValue(value);
}
diff --git a/v14/preference/src/android/support/v14/preference/MultiSelectListPreferenceDialogFragment.java b/v14/preference/src/android/support/v14/preference/MultiSelectListPreferenceDialogFragment.java
index ec46aac..5b585bc 100644
--- a/v14/preference/src/android/support/v14/preference/MultiSelectListPreferenceDialogFragment.java
+++ b/v14/preference/src/android/support/v14/preference/MultiSelectListPreferenceDialogFragment.java
@@ -19,14 +19,27 @@
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
+import android.support.annotation.NonNull;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
public class MultiSelectListPreferenceDialogFragment extends PreferenceDialogFragment {
+ private static final String SAVE_STATE_VALUES =
+ "MultiSelectListPreferenceDialogFragment.values";
+ private static final String SAVE_STATE_CHANGED =
+ "MultiSelectListPreferenceDialogFragment.changed";
+ private static final String SAVE_STATE_ENTRIES =
+ "MultiSelectListPreferenceDialogFragment.entries";
+ private static final String SAVE_STATE_ENTRY_VALUES =
+ "MultiSelectListPreferenceDialogFragment.entryValues";
+
private Set<String> mNewValues = new HashSet<>();
private boolean mPreferenceChanged;
+ private CharSequence[] mEntries;
+ private CharSequence[] mEntryValues;
public static MultiSelectListPreferenceDialogFragment newInstance(String key) {
final MultiSelectListPreferenceDialogFragment fragment =
@@ -37,6 +50,42 @@
return fragment;
}
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (savedInstanceState == null) {
+ final MultiSelectListPreference 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 MultiSelectListPreference getListPreference() {
return (MultiSelectListPreference) getPreference();
}
@@ -45,29 +94,23 @@
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
super.onPrepareDialogBuilder(builder);
- final MultiSelectListPreference preference = getListPreference();
-
- if (preference.getEntries() == null || preference.getEntryValues() == null) {
- throw new IllegalStateException(
- "MultiSelectListPreference requires an entries array and " +
- "an entryValues array.");
+ 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());
}
-
- boolean[] checkedItems = preference.getSelectedItems();
- builder.setMultiChoiceItems(preference.getEntries(), checkedItems,
+ builder.setMultiChoiceItems(mEntries, checkedItems,
new DialogInterface.OnMultiChoiceClickListener() {
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
if (isChecked) {
mPreferenceChanged |= mNewValues.add(
- preference.getEntryValues()[which].toString());
+ mEntryValues[which].toString());
} else {
mPreferenceChanged |= mNewValues.remove(
- preference.getEntryValues()[which].toString());
+ mEntryValues[which].toString());
}
}
});
- mNewValues.clear();
- mNewValues.addAll(preference.getValues());
}
@Override
diff --git a/v14/preference/src/android/support/v14/preference/PreferenceDialogFragment.java b/v14/preference/src/android/support/v14/preference/PreferenceDialogFragment.java
index 8f5dd64..48b404e 100644
--- a/v14/preference/src/android/support/v14/preference/PreferenceDialogFragment.java
+++ b/v14/preference/src/android/support/v14/preference/PreferenceDialogFragment.java
@@ -22,7 +22,12 @@
import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.v7.preference.DialogPreference;
import android.text.TextUtils;
@@ -32,13 +37,35 @@
import android.view.WindowManager;
import android.widget.TextView;
+/**
+ * Abstract base class which presents a dialog associated with a
+ * {@link android.support.v7.preference.DialogPreference}. Since the preference object may
+ * not be available during fragment re-creation, the necessary information for displaying the dialog
+ * is read once during the initial call to {@link #onCreate(Bundle)} and saved/restored in the saved
+ * instance state. Custom subclasses should also follow this pattern.
+ */
public abstract class PreferenceDialogFragment extends DialogFragment implements
DialogInterface.OnClickListener {
protected static final String ARG_KEY = "key";
+ private static final String SAVE_STATE_TITLE = "PreferenceDialogFragment.title";
+ private static final String SAVE_STATE_POSITIVE_TEXT = "PreferenceDialogFragment.positiveText";
+ private static final String SAVE_STATE_NEGATIVE_TEXT = "PreferenceDialogFragment.negativeText";
+ private static final String SAVE_STATE_MESSAGE = "PreferenceDialogFragment.message";
+ private static final String SAVE_STATE_LAYOUT = "PreferenceDialogFragment.layout";
+ private static final String SAVE_STATE_ICON = "PreferenceDialogFragment.icon";
+
private DialogPreference mPreference;
+ private CharSequence mDialogTitle;
+ private CharSequence mPositiveButtonText;
+ private CharSequence mNegativeButtonText;
+ private CharSequence mDialogMessage;
+ private @LayoutRes int mDialogLayoutRes;
+
+ private BitmapDrawable mDialogIcon;
+
/** Which button was clicked. */
private int mWhichButtonClicked;
@@ -56,7 +83,50 @@
(DialogPreference.TargetFragment) rawFragment;
final String key = getArguments().getString(ARG_KEY);
- mPreference = (DialogPreference) fragment.findPreference(key);
+ if (savedInstanceState == null) {
+ mPreference = (DialogPreference) fragment.findPreference(key);
+ mDialogTitle = mPreference.getDialogTitle();
+ mPositiveButtonText = mPreference.getPositiveButtonText();
+ mNegativeButtonText = mPreference.getNegativeButtonText();
+ mDialogMessage = mPreference.getDialogMessage();
+ mDialogLayoutRes = mPreference.getDialogLayoutResource();
+
+ final Drawable icon = mPreference.getDialogIcon();
+ if (icon == null || icon instanceof BitmapDrawable) {
+ mDialogIcon = (BitmapDrawable) icon;
+ } else {
+ final Bitmap bitmap = Bitmap.createBitmap(icon.getIntrinsicWidth(),
+ icon.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
+ final Canvas canvas = new Canvas(bitmap);
+ icon.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+ icon.draw(canvas);
+ mDialogIcon = new BitmapDrawable(getResources(), bitmap);
+ }
+ } else {
+ mDialogTitle = savedInstanceState.getCharSequence(SAVE_STATE_TITLE);
+ mPositiveButtonText = savedInstanceState.getCharSequence(SAVE_STATE_POSITIVE_TEXT);
+ mNegativeButtonText = savedInstanceState.getCharSequence(SAVE_STATE_NEGATIVE_TEXT);
+ mDialogMessage = savedInstanceState.getCharSequence(SAVE_STATE_MESSAGE);
+ mDialogLayoutRes = savedInstanceState.getInt(SAVE_STATE_LAYOUT, 0);
+ final Bitmap bitmap = savedInstanceState.getParcelable(SAVE_STATE_ICON);
+ if (bitmap != null) {
+ mDialogIcon = new BitmapDrawable(getResources(), bitmap);
+ }
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(@NonNull Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ outState.putCharSequence(SAVE_STATE_TITLE, mDialogTitle);
+ outState.putCharSequence(SAVE_STATE_POSITIVE_TEXT, mPositiveButtonText);
+ outState.putCharSequence(SAVE_STATE_NEGATIVE_TEXT, mNegativeButtonText);
+ outState.putCharSequence(SAVE_STATE_MESSAGE, mDialogMessage);
+ outState.putInt(SAVE_STATE_LAYOUT, mDialogLayoutRes);
+ if (mDialogIcon != null) {
+ outState.putParcelable(SAVE_STATE_ICON, mDialogIcon.getBitmap());
+ }
}
@Override
@@ -66,17 +136,17 @@
mWhichButtonClicked = DialogInterface.BUTTON_NEGATIVE;
final AlertDialog.Builder builder = new AlertDialog.Builder(context)
- .setTitle(mPreference.getDialogTitle())
- .setIcon(mPreference.getDialogIcon())
- .setPositiveButton(mPreference.getPositiveButtonText(), this)
- .setNegativeButton(mPreference.getNegativeButtonText(), this);
+ .setTitle(mDialogTitle)
+ .setIcon(mDialogIcon)
+ .setPositiveButton(mPositiveButtonText, this)
+ .setNegativeButton(mNegativeButtonText, this);
View contentView = onCreateDialogView(context);
if (contentView != null) {
onBindDialogView(contentView);
builder.setView(contentView);
} else {
- builder.setMessage(mPreference.getDialogMessage());
+ builder.setMessage(mDialogMessage);
}
onPrepareDialogBuilder(builder);
@@ -92,12 +162,18 @@
/**
* Get the preference that requested this dialog. Available after {@link #onCreate(Bundle)} has
- * been called.
+ * been called on the {@link PreferenceFragment} which launched this dialog.
*
* @return The {@link DialogPreference} associated with this
* dialog.
*/
public DialogPreference getPreference() {
+ if (mPreference == null) {
+ final String key = getArguments().getString(ARG_KEY);
+ final DialogPreference.TargetFragment fragment =
+ (DialogPreference.TargetFragment) getTargetFragment();
+ mPreference = (DialogPreference) fragment.findPreference(key);
+ }
return mPreference;
}
@@ -137,7 +213,7 @@
* @see DialogPreference#setLayoutResource(int)
*/
protected View onCreateDialogView(Context context) {
- final int resId = mPreference.getDialogLayoutResource();
+ final int resId = mDialogLayoutRes;
if (resId == 0) {
return null;
}
@@ -157,7 +233,7 @@
View dialogMessageView = view.findViewById(android.R.id.message);
if (dialogMessageView != null) {
- final CharSequence message = mPreference.getDialogMessage();
+ final CharSequence message = mDialogMessage;
int newVisibility = View.GONE;
if (!TextUtils.isEmpty(message)) {
diff --git a/v7/preference/src/android/support/v7/preference/EditTextPreferenceDialogFragmentCompat.java b/v7/preference/src/android/support/v7/preference/EditTextPreferenceDialogFragmentCompat.java
index 6e7663c..2abafe7 100644
--- a/v7/preference/src/android/support/v7/preference/EditTextPreferenceDialogFragmentCompat.java
+++ b/v7/preference/src/android/support/v7/preference/EditTextPreferenceDialogFragmentCompat.java
@@ -17,13 +17,18 @@
package android.support.v7.preference;
import android.os.Bundle;
+import android.support.annotation.NonNull;
import android.view.View;
import android.widget.EditText;
public class EditTextPreferenceDialogFragmentCompat extends PreferenceDialogFragmentCompat {
+ private static final String SAVE_STATE_TEXT = "EditTextPreferenceDialogFragment.text";
+
private EditText mEditText;
+ private CharSequence mText;
+
public static EditTextPreferenceDialogFragmentCompat newInstance(String key) {
final EditTextPreferenceDialogFragmentCompat
fragment = new EditTextPreferenceDialogFragmentCompat();
@@ -34,6 +39,22 @@
}
@Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (savedInstanceState == null) {
+ mText = getEditTextPreference().getText();
+ } else {
+ mText = savedInstanceState.getCharSequence(SAVE_STATE_TEXT);
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(@NonNull Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putCharSequence(SAVE_STATE_TEXT, mText);
+ }
+
+ @Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
@@ -44,7 +65,7 @@
" @android:id/edit");
}
- mEditText.setText(getEditTextPreference().getText());
+ mEditText.setText(mText);
}
private EditTextPreference getEditTextPreference() {
diff --git a/v7/preference/src/android/support/v7/preference/ListPreferenceDialogFragmentCompat.java b/v7/preference/src/android/support/v7/preference/ListPreferenceDialogFragmentCompat.java
index 351ed0b..dda461d 100644
--- a/v7/preference/src/android/support/v7/preference/ListPreferenceDialogFragmentCompat.java
+++ b/v7/preference/src/android/support/v7/preference/ListPreferenceDialogFragmentCompat.java
@@ -18,11 +18,21 @@
import android.content.DialogInterface;
import android.os.Bundle;
+import android.support.annotation.NonNull;
import android.support.v7.app.AlertDialog;
+import java.util.ArrayList;
+
public class ListPreferenceDialogFragmentCompat extends PreferenceDialogFragmentCompat {
+ private static final String SAVE_STATE_INDEX = "ListPreferenceDialogFragment.index";
+ private static final String SAVE_STATE_ENTRIES = "ListPreferenceDialogFragment.entries";
+ private static final String SAVE_STATE_ENTRY_VALUES =
+ "ListPreferenceDialogFragment.entryValues";
+
private int mClickedDialogEntryIndex;
+ private CharSequence[] mEntries;
+ private CharSequence[] mEntryValues;
public static ListPreferenceDialogFragmentCompat newInstance(String key) {
final ListPreferenceDialogFragmentCompat fragment =
@@ -33,6 +43,51 @@
return fragment;
}
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (savedInstanceState == null) {
+ final ListPreference preference = getListPreference();
+
+ if (preference.getEntries() == null || preference.getEntryValues() == null) {
+ throw new IllegalStateException(
+ "ListPreference requires an entries array and an entryValues array.");
+ }
+
+ mClickedDialogEntryIndex = preference.findIndexOfValue(preference.getValue());
+ mEntries = preference.getEntries();
+ mEntryValues = preference.getEntryValues();
+ } else {
+ mClickedDialogEntryIndex = savedInstanceState.getInt(SAVE_STATE_INDEX, 0);
+ mEntries = getCharSequenceArray(savedInstanceState, SAVE_STATE_ENTRIES);
+ mEntryValues = getCharSequenceArray(savedInstanceState, SAVE_STATE_ENTRY_VALUES);
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(@NonNull Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putInt(SAVE_STATE_INDEX, mClickedDialogEntryIndex);
+ putCharSequenceArray(outState, SAVE_STATE_ENTRIES, mEntries);
+ putCharSequenceArray(outState, SAVE_STATE_ENTRY_VALUES, mEntryValues);
+ }
+
+ private static void putCharSequenceArray(Bundle out, String key, CharSequence[] entries) {
+ final ArrayList<String> stored = new ArrayList<>(entries.length);
+
+ for (final CharSequence cs : entries) {
+ stored.add(cs.toString());
+ }
+
+ out.putStringArrayList(key, stored);
+ }
+
+ private static CharSequence[] getCharSequenceArray(Bundle in, String key) {
+ final ArrayList<String> stored = in.getStringArrayList(key);
+
+ return stored == null ? null : stored.toArray(new CharSequence[stored.size()]);
+ }
+
private ListPreference getListPreference() {
return (ListPreference) getPreference();
}
@@ -41,15 +96,7 @@
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
super.onPrepareDialogBuilder(builder);
- final ListPreference preference = getListPreference();
-
- if (preference.getEntries() == null || preference.getEntryValues() == null) {
- throw new IllegalStateException(
- "ListPreference requires an entries array and an entryValues array.");
- }
-
- mClickedDialogEntryIndex = preference.findIndexOfValue(preference.getValue());
- builder.setSingleChoiceItems(preference.getEntries(), mClickedDialogEntryIndex,
+ builder.setSingleChoiceItems(mEntries, mClickedDialogEntryIndex,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mClickedDialogEntryIndex = which;
@@ -75,9 +122,8 @@
@Override
public void onDialogClosed(boolean positiveResult) {
final ListPreference preference = getListPreference();
- if (positiveResult && mClickedDialogEntryIndex >= 0 &&
- preference.getEntryValues() != null) {
- String value = preference.getEntryValues()[mClickedDialogEntryIndex].toString();
+ if (positiveResult && mClickedDialogEntryIndex >= 0) {
+ String value = mEntryValues[mClickedDialogEntryIndex].toString();
if (preference.callChangeListener(value)) {
preference.setValue(value);
}
diff --git a/v7/preference/src/android/support/v7/preference/PreferenceDialogFragmentCompat.java b/v7/preference/src/android/support/v7/preference/PreferenceDialogFragmentCompat.java
index 6bc2df0..9b6fd5a 100644
--- a/v7/preference/src/android/support/v7/preference/PreferenceDialogFragmentCompat.java
+++ b/v7/preference/src/android/support/v7/preference/PreferenceDialogFragmentCompat.java
@@ -19,7 +19,12 @@
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
@@ -31,13 +36,35 @@
import android.view.WindowManager;
import android.widget.TextView;
+/**
+ * Abstract base class which presents a dialog associated with a
+ * {@link android.support.v7.preference.DialogPreference}. Since the preference object may
+ * not be available during fragment re-creation, the necessary information for displaying the dialog
+ * is read once during the initial call to {@link #onCreate(Bundle)} and saved/restored in the saved
+ * instance state. Custom subclasses should also follow this pattern.
+ */
public abstract class PreferenceDialogFragmentCompat extends DialogFragment implements
DialogInterface.OnClickListener {
protected static final String ARG_KEY = "key";
+ private static final String SAVE_STATE_TITLE = "PreferenceDialogFragment.title";
+ private static final String SAVE_STATE_POSITIVE_TEXT = "PreferenceDialogFragment.positiveText";
+ private static final String SAVE_STATE_NEGATIVE_TEXT = "PreferenceDialogFragment.negativeText";
+ private static final String SAVE_STATE_MESSAGE = "PreferenceDialogFragment.message";
+ private static final String SAVE_STATE_LAYOUT = "PreferenceDialogFragment.layout";
+ private static final String SAVE_STATE_ICON = "PreferenceDialogFragment.icon";
+
private DialogPreference mPreference;
+ private CharSequence mDialogTitle;
+ private CharSequence mPositiveButtonText;
+ private CharSequence mNegativeButtonText;
+ private CharSequence mDialogMessage;
+ private @LayoutRes int mDialogLayoutRes;
+
+ private BitmapDrawable mDialogIcon;
+
/** Which button was clicked. */
private int mWhichButtonClicked;
@@ -55,26 +82,70 @@
(DialogPreference.TargetFragment) rawFragment;
final String key = getArguments().getString(ARG_KEY);
- mPreference = (DialogPreference) fragment.findPreference(key);
+ if (savedInstanceState == null) {
+ mPreference = (DialogPreference) fragment.findPreference(key);
+ mDialogTitle = mPreference.getDialogTitle();
+ mPositiveButtonText = mPreference.getPositiveButtonText();
+ mNegativeButtonText = mPreference.getNegativeButtonText();
+ mDialogMessage = mPreference.getDialogMessage();
+ mDialogLayoutRes = mPreference.getDialogLayoutResource();
+
+ final Drawable icon = mPreference.getDialogIcon();
+ if (icon == null || icon instanceof BitmapDrawable) {
+ mDialogIcon = (BitmapDrawable) icon;
+ } else {
+ final Bitmap bitmap = Bitmap.createBitmap(icon.getIntrinsicWidth(),
+ icon.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
+ final Canvas canvas = new Canvas(bitmap);
+ icon.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+ icon.draw(canvas);
+ mDialogIcon = new BitmapDrawable(getResources(), bitmap);
+ }
+ } else {
+ mDialogTitle = savedInstanceState.getCharSequence(SAVE_STATE_TITLE);
+ mPositiveButtonText = savedInstanceState.getCharSequence(SAVE_STATE_POSITIVE_TEXT);
+ mNegativeButtonText = savedInstanceState.getCharSequence(SAVE_STATE_NEGATIVE_TEXT);
+ mDialogMessage = savedInstanceState.getCharSequence(SAVE_STATE_MESSAGE);
+ mDialogLayoutRes = savedInstanceState.getInt(SAVE_STATE_LAYOUT, 0);
+ final Bitmap bitmap = savedInstanceState.getParcelable(SAVE_STATE_ICON);
+ if (bitmap != null) {
+ mDialogIcon = new BitmapDrawable(getResources(), bitmap);
+ }
+ }
}
@Override
- public @NonNull Dialog onCreateDialog(Bundle savedInstanceState) {
+ public void onSaveInstanceState(@NonNull Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ outState.putCharSequence(SAVE_STATE_TITLE, mDialogTitle);
+ outState.putCharSequence(SAVE_STATE_POSITIVE_TEXT, mPositiveButtonText);
+ outState.putCharSequence(SAVE_STATE_NEGATIVE_TEXT, mNegativeButtonText);
+ outState.putCharSequence(SAVE_STATE_MESSAGE, mDialogMessage);
+ outState.putInt(SAVE_STATE_LAYOUT, mDialogLayoutRes);
+ if (mDialogIcon != null) {
+ outState.putParcelable(SAVE_STATE_ICON, mDialogIcon.getBitmap());
+ }
+ }
+
+ @Override
+ public @NonNull
+ Dialog onCreateDialog(Bundle savedInstanceState) {
final Context context = getActivity();
mWhichButtonClicked = DialogInterface.BUTTON_NEGATIVE;
final AlertDialog.Builder builder = new AlertDialog.Builder(context)
- .setTitle(mPreference.getDialogTitle())
- .setIcon(mPreference.getDialogIcon())
- .setPositiveButton(mPreference.getPositiveButtonText(), this)
- .setNegativeButton(mPreference.getNegativeButtonText(), this);
+ .setTitle(mDialogTitle)
+ .setIcon(mDialogIcon)
+ .setPositiveButton(mPositiveButtonText, this)
+ .setNegativeButton(mNegativeButtonText, this);
View contentView = onCreateDialogView(context);
if (contentView != null) {
onBindDialogView(contentView);
builder.setView(contentView);
} else {
- builder.setMessage(mPreference.getDialogMessage());
+ builder.setMessage(mDialogMessage);
}
onPrepareDialogBuilder(builder);
@@ -90,12 +161,18 @@
/**
* Get the preference that requested this dialog. Available after {@link #onCreate(Bundle)} has
- * been called.
+ * been called on the {@link PreferenceFragmentCompat} which launched this dialog.
*
* @return The {@link DialogPreference} associated with this
* dialog.
*/
public DialogPreference getPreference() {
+ if (mPreference == null) {
+ final String key = getArguments().getString(ARG_KEY);
+ final DialogPreference.TargetFragment fragment =
+ (DialogPreference.TargetFragment) getTargetFragment();
+ mPreference = (DialogPreference) fragment.findPreference(key);
+ }
return mPreference;
}
@@ -135,7 +212,7 @@
* @see DialogPreference#setLayoutResource(int)
*/
protected View onCreateDialogView(Context context) {
- final int resId = mPreference.getDialogLayoutResource();
+ final int resId = mDialogLayoutRes;
if (resId == 0) {
return null;
}
@@ -155,7 +232,7 @@
View dialogMessageView = view.findViewById(android.R.id.message);
if (dialogMessageView != null) {
- final CharSequence message = mPreference.getDialogMessage();
+ final CharSequence message = mDialogMessage;
int newVisibility = View.GONE;
if (!TextUtils.isEmpty(message)) {