diff options
| author | 2018-10-02 21:34:07 +0000 | |
|---|---|---|
| committer | 2018-10-02 21:34:07 +0000 | |
| commit | 9b2c026f10f98dee726886ea1fadb698c9619456 (patch) | |
| tree | aaf51ab97c84edcc10f04dfe2c72e1b392d8cff4 | |
| parent | 604b0eed1ff3f6f29c52395db8b986e7af181f6d (diff) | |
| parent | 5692a8ba5f8ff1ac988cbaf2622cc217d724109d (diff) | |
Merge "Dismiss Dialog in post instead of immediately"
| -rw-r--r-- | core/java/android/preference/DialogPreference.java | 128 | ||||
| -rw-r--r-- | core/java/android/preference/ListPreference.java | 44 |
2 files changed, 100 insertions, 72 deletions
diff --git a/core/java/android/preference/DialogPreference.java b/core/java/android/preference/DialogPreference.java index 534ef8d8e0e9..4b5a7b40fe44 100644 --- a/core/java/android/preference/DialogPreference.java +++ b/core/java/android/preference/DialogPreference.java @@ -43,7 +43,7 @@ import android.widget.TextView; * A base class for {@link Preference} objects that are * dialog-based. These preferences will, when clicked, open a dialog showing the * actual preference controls. - * + * * @attr ref android.R.styleable#DialogPreference_dialogTitle * @attr ref android.R.styleable#DialogPreference_dialogMessage * @attr ref android.R.styleable#DialogPreference_dialogIcon @@ -56,7 +56,7 @@ public abstract class DialogPreference extends Preference implements PreferenceManager.OnActivityDestroyListener { @UnsupportedAppUsage private AlertDialog.Builder mBuilder; - + @UnsupportedAppUsage private CharSequence mDialogTitle; @UnsupportedAppUsage @@ -77,6 +77,14 @@ public abstract class DialogPreference extends Preference implements @UnsupportedAppUsage private int mWhichButtonClicked; + /** Dismiss the dialog on the UI thread, but not inline with handlers */ + private final Runnable mDismissRunnable = new Runnable() { + @Override + public void run() { + mDialog.dismiss(); + } + }; + public DialogPreference( Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); @@ -112,7 +120,7 @@ public abstract class DialogPreference extends Preference implements /** * Sets the title of the dialog. This will be shown on subsequent dialogs. - * + * * @param dialogTitle The title. */ public void setDialogTitle(CharSequence dialogTitle) { @@ -126,7 +134,7 @@ public abstract class DialogPreference extends Preference implements public void setDialogTitle(int dialogTitleResId) { setDialogTitle(getContext().getString(dialogTitleResId)); } - + /** * Returns the title to be shown on subsequent dialogs. * @return The title. @@ -134,7 +142,7 @@ public abstract class DialogPreference extends Preference implements public CharSequence getDialogTitle() { return mDialogTitle; } - + /** * Sets the message of the dialog. This will be shown on subsequent dialogs. * <p> @@ -142,7 +150,7 @@ public abstract class DialogPreference extends Preference implements * list-based dialogs, for example. If setting a custom View on a dialog via * {@link #setDialogLayoutResource(int)}, include a text View with ID * {@link android.R.id#message} and it will be populated with this message. - * + * * @param dialogMessage The message. */ public void setDialogMessage(CharSequence dialogMessage) { @@ -156,7 +164,7 @@ public abstract class DialogPreference extends Preference implements public void setDialogMessage(int dialogMessageResId) { setDialogMessage(getContext().getString(dialogMessageResId)); } - + /** * Returns the message to be shown on subsequent dialogs. * @return The message. @@ -164,26 +172,26 @@ public abstract class DialogPreference extends Preference implements public CharSequence getDialogMessage() { return mDialogMessage; } - + /** * Sets the icon of the dialog. This will be shown on subsequent dialogs. - * + * * @param dialogIcon The icon, as a {@link Drawable}. */ public void setDialogIcon(Drawable dialogIcon) { mDialogIcon = dialogIcon; } - + /** * Sets the icon (resource ID) of the dialog. This will be shown on * subsequent dialogs. - * + * * @param dialogIconRes The icon, as a resource ID. */ public void setDialogIcon(@DrawableRes int dialogIconRes) { mDialogIcon = getContext().getDrawable(dialogIconRes); } - + /** * Returns the icon to be shown on subsequent dialogs. * @return The icon, as a {@link Drawable}. @@ -191,11 +199,11 @@ public abstract class DialogPreference extends Preference implements public Drawable getDialogIcon() { return mDialogIcon; } - + /** * Sets the text of the positive button of the dialog. This will be shown on * subsequent dialogs. - * + * * @param positiveButtonText The text of the positive button. */ public void setPositiveButtonText(CharSequence positiveButtonText) { @@ -209,27 +217,27 @@ public abstract class DialogPreference extends Preference implements public void setPositiveButtonText(@StringRes int positiveButtonTextResId) { setPositiveButtonText(getContext().getString(positiveButtonTextResId)); } - + /** * Returns the text of the positive button to be shown on subsequent * dialogs. - * + * * @return The text of the positive button. */ public CharSequence getPositiveButtonText() { return mPositiveButtonText; } - + /** * Sets the text of the negative button of the dialog. This will be shown on * subsequent dialogs. - * + * * @param negativeButtonText The text of the negative button. */ public void setNegativeButtonText(CharSequence negativeButtonText) { mNegativeButtonText = negativeButtonText; } - + /** * @see #setNegativeButtonText(CharSequence) * @param negativeButtonTextResId The negative button text as a resource. @@ -237,38 +245,38 @@ public abstract class DialogPreference extends Preference implements public void setNegativeButtonText(@StringRes int negativeButtonTextResId) { setNegativeButtonText(getContext().getString(negativeButtonTextResId)); } - + /** * Returns the text of the negative button to be shown on subsequent * dialogs. - * + * * @return The text of the negative button. */ public CharSequence getNegativeButtonText() { return mNegativeButtonText; } - + /** * Sets the layout resource that is inflated as the {@link View} to be shown * as the content View of subsequent dialogs. - * + * * @param dialogLayoutResId The layout resource ID to be inflated. * @see #setDialogMessage(CharSequence) */ public void setDialogLayoutResource(int dialogLayoutResId) { mDialogLayoutResId = dialogLayoutResId; } - + /** * Returns the layout resource that is used as the content View for * subsequent dialogs. - * + * * @return The layout resource. */ public int getDialogLayoutResource() { return mDialogLayoutResId; } - + /** * Prepares the dialog builder to be shown when the preference is clicked. * Use this to set custom properties on the dialog. @@ -278,7 +286,7 @@ public abstract class DialogPreference extends Preference implements */ protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { } - + @Override protected void onClick() { if (mDialog != null && mDialog.isShowing()) return; @@ -290,14 +298,14 @@ public abstract class DialogPreference extends Preference implements * Shows the dialog associated with this Preference. This is normally initiated * automatically on clicking on the preference. Call this method if you need to * show the dialog on some other event. - * + * * @param state Optional instance state to restore on the dialog */ protected void showDialog(Bundle state) { Context context = getContext(); mWhichButtonClicked = DialogInterface.BUTTON_NEGATIVE; - + mBuilder = new AlertDialog.Builder(context) .setTitle(mDialogTitle) .setIcon(mDialogIcon) @@ -311,11 +319,11 @@ public abstract class DialogPreference extends Preference implements } else { mBuilder.setMessage(mDialogMessage); } - + onPrepareDialogBuilder(mBuilder); - + getPreferenceManager().registerOnActivityDestroyListener(this); - + // Create the dialog final Dialog dialog = mDialog = mBuilder.create(); if (state != null) { @@ -324,10 +332,29 @@ public abstract class DialogPreference extends Preference implements if (needInputMethod()) { requestInputMethod(dialog); } + dialog.setOnShowListener(new DialogInterface.OnShowListener() { + @Override + public void onShow(DialogInterface dialog) { + removeDismissCallbacks(); + } + }); dialog.setOnDismissListener(this); dialog.show(); } + void postDismiss() { + removeDismissCallbacks(); + View decorView = mDialog.getWindow().getDecorView(); + decorView.post(mDismissRunnable); + } + + private void removeDismissCallbacks() { + if (mDialog != null && mDialog.getWindow() != null + && mDialog.getWindow().getDecorView() != null) { + mDialog.getWindow().getDecorView().removeCallbacks(mDismissRunnable); + } + } + /** * Returns whether the preference needs to display a soft input method when the dialog * is displayed. Default is false. Subclasses should override this method if they need @@ -350,7 +377,7 @@ public abstract class DialogPreference extends Preference implements * Creates the content view for the dialog (if a custom content view is * required). By default, it inflates the dialog layout resource if it is * set. - * + * * @return The content View for the dialog. * @see #setLayoutResource(int) */ @@ -358,48 +385,49 @@ public abstract class DialogPreference extends Preference implements if (mDialogLayoutResId == 0) { return null; } - + LayoutInflater inflater = LayoutInflater.from(mBuilder.getContext()); return inflater.inflate(mDialogLayoutResId, null); } - + /** * Binds views in the content View of the dialog to data. * <p> * Make sure to call through to the superclass implementation. - * + * * @param view The content View of the dialog, if it is custom. */ @CallSuper protected void onBindDialogView(View view) { View dialogMessageView = view.findViewById(com.android.internal.R.id.message); - + if (dialogMessageView != null) { final CharSequence message = getDialogMessage(); int newVisibility = View.GONE; - + if (!TextUtils.isEmpty(message)) { if (dialogMessageView instanceof TextView) { ((TextView) dialogMessageView).setText(message); } - + newVisibility = View.VISIBLE; } - + if (dialogMessageView.getVisibility() != newVisibility) { dialogMessageView.setVisibility(newVisibility); } } } - + public void onClick(DialogInterface dialog, int which) { mWhichButtonClicked = which; } - + + @Override public void onDismiss(DialogInterface dialog) { - + removeDismissCallbacks(); getPreferenceManager().unregisterOnActivityDestroyListener(this); - + mDialog = null; onDialogClosed(mWhichButtonClicked == DialogInterface.BUTTON_POSITIVE); } @@ -407,7 +435,7 @@ public abstract class DialogPreference extends Preference implements /** * Called when the dialog is dismissed and should be used to save data to * the {@link SharedPreferences}. - * + * * @param positiveResult Whether the positive button was clicked (true), or * the negative button was clicked or the dialog was canceled (false). */ @@ -416,7 +444,7 @@ public abstract class DialogPreference extends Preference implements /** * Gets the dialog that is shown by this preference. - * + * * @return The dialog, or null if a dialog is not being shown. */ public Dialog getDialog() { @@ -427,11 +455,11 @@ public abstract class DialogPreference extends Preference implements * {@inheritDoc} */ public void onActivityDestroy() { - + if (mDialog == null || !mDialog.isShowing()) { return; } - + mDialog.dismiss(); } @@ -466,7 +494,7 @@ public abstract class DialogPreference extends Preference implements private static class SavedState extends BaseSavedState { boolean isDialogShowing; Bundle dialogBundle; - + public SavedState(Parcel source) { super(source); isDialogShowing = source.readInt() == 1; @@ -495,5 +523,5 @@ public abstract class DialogPreference extends Preference implements } }; } - + } diff --git a/core/java/android/preference/ListPreference.java b/core/java/android/preference/ListPreference.java index e7dec0ec2bba..c0c71af8639e 100644 --- a/core/java/android/preference/ListPreference.java +++ b/core/java/android/preference/ListPreference.java @@ -33,7 +33,7 @@ import android.util.AttributeSet; * <p> * This preference will store a string into the SharedPreferences. This string will be the value * from the {@link #setEntryValues(CharSequence[])} array. - * + * * @attr ref android.R.styleable#ListPreference_entries * @attr ref android.R.styleable#ListPreference_entryValues */ @@ -193,7 +193,7 @@ public class ListPreference extends DialogPreference { /** * Sets the value to the given index from the entry values. - * + * * @param index The index of the value to set. */ public void setValueIndex(int index) { @@ -201,30 +201,30 @@ public class ListPreference extends DialogPreference { setValue(mEntryValues[index].toString()); } } - + /** * Returns the value of the key. This should be one of the entries in * {@link #getEntryValues()}. - * + * * @return The value of the key. */ public String getValue() { - return mValue; + return mValue; } - + /** * Returns the entry corresponding to the current value. - * + * * @return The entry corresponding to the current value, or null. */ public CharSequence getEntry() { int index = getValueIndex(); return index >= 0 && mEntries != null ? mEntries[index] : null; } - + /** * Returns the index of the given value (in the entry values array). - * + * * @param value The value whose index should be returned. * @return The index of the value, or -1 if not found. */ @@ -238,22 +238,22 @@ public class ListPreference extends DialogPreference { } return -1; } - + private int getValueIndex() { return findIndexOfValue(mValue); } - + @Override protected void onPrepareDialogBuilder(Builder builder) { super.onPrepareDialogBuilder(builder); - + if (mEntries == null || mEntryValues == null) { throw new IllegalStateException( "ListPreference requires an entries array and an entryValues array."); } mClickedDialogEntryIndex = getValueIndex(); - builder.setSingleChoiceItems(mEntries, mClickedDialogEntryIndex, + builder.setSingleChoiceItems(mEntries, mClickedDialogEntryIndex, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { mClickedDialogEntryIndex = which; @@ -263,10 +263,10 @@ public class ListPreference extends DialogPreference { * click, and dismisses the dialog. */ ListPreference.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE); - dialog.dismiss(); + postDismiss(); } }); - + /* * The typical interaction for list-based dialogs is to have * click-on-an-item dismiss the dialog instead of the user having to @@ -278,7 +278,7 @@ public class ListPreference extends DialogPreference { @Override protected void onDialogClosed(boolean positiveResult) { super.onDialogClosed(positiveResult); - + if (positiveResult && mClickedDialogEntryIndex >= 0 && mEntryValues != null) { String value = mEntryValues[mClickedDialogEntryIndex].toString(); if (callChangeListener(value)) { @@ -296,7 +296,7 @@ public class ListPreference extends DialogPreference { protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { setValue(restoreValue ? getPersistedString(mValue) : (String) defaultValue); } - + @Override protected Parcelable onSaveInstanceState() { final Parcelable superState = super.onSaveInstanceState(); @@ -304,7 +304,7 @@ public class ListPreference extends DialogPreference { // No need to save instance state since it's persistent return superState; } - + final SavedState myState = new SavedState(superState); myState.value = getValue(); return myState; @@ -317,15 +317,15 @@ public class ListPreference extends DialogPreference { super.onRestoreInstanceState(state); return; } - + SavedState myState = (SavedState) state; super.onRestoreInstanceState(myState.getSuperState()); setValue(myState.value); } - + private static class SavedState extends BaseSavedState { String value; - + public SavedState(Parcel source) { super(source); value = source.readString(); @@ -352,5 +352,5 @@ public class ListPreference extends DialogPreference { } }; } - + } |