diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
commit | 54b6cfa9a9e5b861a9930af873580d6dc20f773c (patch) | |
tree | 35051494d2af230dce54d6b31c6af8fc24091316 /core/java/android/preference/DialogPreference.java | |
download | frameworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.zip frameworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.tar.gz frameworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.tar.bz2 |
Initial Contribution
Diffstat (limited to 'core/java/android/preference/DialogPreference.java')
-rw-r--r-- | core/java/android/preference/DialogPreference.java | 445 |
1 files changed, 445 insertions, 0 deletions
diff --git a/core/java/android/preference/DialogPreference.java b/core/java/android/preference/DialogPreference.java new file mode 100644 index 0000000..3eb65e2 --- /dev/null +++ b/core/java/android/preference/DialogPreference.java @@ -0,0 +1,445 @@ +/* + * Copyright (C) 2007 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.preference; + + +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.content.res.TypedArray; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.TextView; + +/** + * The {@link DialogPreference} class is a base class for preferences 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 + * @attr ref android.R.styleable#DialogPreference_dialogLayout + * @attr ref android.R.styleable#DialogPreference_positiveButtonText + * @attr ref android.R.styleable#DialogPreference_negativeButtonText + */ +public abstract class DialogPreference extends Preference implements + DialogInterface.OnClickListener, DialogInterface.OnDismissListener, + PreferenceManager.OnActivityDestroyListener { + private AlertDialog.Builder mBuilder; + + private CharSequence mDialogTitle; + private CharSequence mDialogMessage; + private Drawable mDialogIcon; + private CharSequence mPositiveButtonText; + private CharSequence mNegativeButtonText; + private int mDialogLayoutResId; + + /** The dialog, if it is showing. */ + private Dialog mDialog; + + /** Which button was clicked. */ + private int mWhichButtonClicked; + + public DialogPreference(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + TypedArray a = context.obtainStyledAttributes(attrs, + com.android.internal.R.styleable.DialogPreference, defStyle, 0); + mDialogTitle = a.getString(com.android.internal.R.styleable.DialogPreference_dialogTitle); + if (mDialogTitle == null) { + // Fallback on the regular title of the preference + // (the one that is seen in the list) + mDialogTitle = getTitle(); + } + mDialogMessage = a.getString(com.android.internal.R.styleable.DialogPreference_dialogMessage); + mDialogIcon = a.getDrawable(com.android.internal.R.styleable.DialogPreference_dialogIcon); + mPositiveButtonText = a.getString(com.android.internal.R.styleable.DialogPreference_positiveButtonText); + mNegativeButtonText = a.getString(com.android.internal.R.styleable.DialogPreference_negativeButtonText); + mDialogLayoutResId = a.getResourceId(com.android.internal.R.styleable.DialogPreference_dialogLayout, + mDialogLayoutResId); + a.recycle(); + + } + + public DialogPreference(Context context, AttributeSet attrs) { + this(context, attrs, com.android.internal.R.attr.dialogPreferenceStyle); + } + + /** + * Sets the title of the dialog. This will be shown on subsequent dialogs. + * + * @param dialogTitle The title. + */ + public void setDialogTitle(CharSequence dialogTitle) { + mDialogTitle = dialogTitle; + } + + /** + * @see #setDialogTitle(CharSequence) + * @param dialogTitleResId The dialog title as a resource. + */ + public void setDialogTitle(int dialogTitleResId) { + setDialogTitle(getContext().getString(dialogTitleResId)); + } + + /** + * Returns the title to be shown on subsequent dialogs. + * @return The title. + */ + public CharSequence getDialogTitle() { + return mDialogTitle; + } + + /** + * Sets the message of the dialog. This will be shown on subsequent dialogs. + * <p> + * This message forms the content View of the dialog and conflicts with + * 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) { + mDialogMessage = dialogMessage; + } + + /** + * @see #setDialogMessage(CharSequence) + * @param dialogMessageResId The dialog message as a resource. + */ + public void setDialogMessage(int dialogMessageResId) { + setDialogMessage(getContext().getString(dialogMessageResId)); + } + + /** + * Returns the message to be shown on subsequent dialogs. + * @return The message. + */ + 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(int dialogIconRes) { + mDialogIcon = getContext().getResources().getDrawable(dialogIconRes); + } + + /** + * Returns the icon to be shown on subsequent dialogs. + * @return The icon, as a {@link Drawable}. + */ + 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) { + mPositiveButtonText = positiveButtonText; + } + + /** + * @see #setPositiveButtonText(CharSequence) + * @param positiveButtonTextResId The positive button text as a resource. + */ + public void setPositiveButtonText(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. + */ + public void setNegativeButtonText(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. + * <p> + * Do not {@link AlertDialog.Builder#create()} or + * {@link AlertDialog.Builder#show()}. + */ + protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { + } + + @Override + protected void onClick() { + showDialog(null); + } + + /** + * 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.BUTTON2; + + mBuilder = new AlertDialog.Builder(context) + .setTitle(mDialogTitle) + .setIcon(mDialogIcon) + .setPositiveButton(mPositiveButtonText, this) + .setNegativeButton(mNegativeButtonText, this); + + View contentView = onCreateDialogView(); + if (contentView != null) { + onBindDialogView(contentView); + mBuilder.setView(contentView); + } else { + mBuilder.setMessage(mDialogMessage); + } + + onPrepareDialogBuilder(mBuilder); + + getPreferenceManager().registerOnActivityDestroyListener(this); + + // Create the dialog + final Dialog dialog = mDialog = mBuilder.create(); + if (state != null) { + dialog.onRestoreInstanceState(state); + } + dialog.setOnDismissListener(this); + dialog.show(); + } + + /** + * 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) + */ + protected View onCreateDialogView() { + if (mDialogLayoutResId == 0) { + return null; + } + + LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + 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. + */ + 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; + } + + public void onDismiss(DialogInterface dialog) { + + getPreferenceManager().unregisterOnActivityDestroyListener(this); + + mDialog = null; + onDialogClosed(mWhichButtonClicked == DialogInterface.BUTTON1); + } + + /** + * 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). + */ + protected void onDialogClosed(boolean positiveResult) { + } + + /** + * {@inheritDoc} + */ + public void onActivityDestroy() { + + if (mDialog == null || !mDialog.isShowing()) { + return; + } + + mDialog.dismiss(); + } + + @Override + protected Parcelable onSaveInstanceState() { + final Parcelable superState = super.onSaveInstanceState(); + if (mDialog == null || !mDialog.isShowing()) { + return superState; + } + + final SavedState myState = new SavedState(superState); + myState.isDialogShowing = true; + myState.dialogBundle = mDialog.onSaveInstanceState(); + return myState; + } + + @Override + protected void onRestoreInstanceState(Parcelable state) { + if (state == null || !state.getClass().equals(SavedState.class)) { + // Didn't save state for us in onSaveInstanceState + super.onRestoreInstanceState(state); + return; + } + + SavedState myState = (SavedState) state; + super.onRestoreInstanceState(myState.getSuperState()); + if (myState.isDialogShowing) { + showDialog(myState.dialogBundle); + } + } + + private static class SavedState extends BaseSavedState { + boolean isDialogShowing; + Bundle dialogBundle; + + public SavedState(Parcel source) { + super(source); + isDialogShowing = source.readInt() == 1; + dialogBundle = source.readBundle(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeInt(isDialogShowing ? 1 : 0); + dest.writeBundle(dialogBundle); + } + + public SavedState(Parcelable superState) { + super(superState); + } + + public static final Parcelable.Creator<SavedState> CREATOR = + new Parcelable.Creator<SavedState>() { + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } + +} |