AlertDialog.java revision 90079ce0ebfcdd61c65d84ce7b3e4521fe755616
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
17package android.support.v7.app;
18
19import android.app.Dialog;
20import android.content.Context;
21import android.content.DialogInterface;
22import android.database.Cursor;
23import android.graphics.drawable.Drawable;
24import android.os.Bundle;
25import android.os.Message;
26import android.support.v7.appcompat.R;
27import android.util.TypedValue;
28import android.view.ContextThemeWrapper;
29import android.view.KeyEvent;
30import android.view.View;
31import android.view.WindowManager;
32import android.widget.AdapterView;
33import android.widget.Button;
34import android.widget.ListAdapter;
35import android.widget.ListView;
36
37/**
38 * A subclass of Dialog that can display one, two or three buttons. If you only want to
39 * display a String in this dialog box, use the setMessage() method.  If you
40 * want to display a more complex view, look up the FrameLayout called "custom"
41 * and add your view to it:
42 *
43 * <pre>
44 * FrameLayout fl = (FrameLayout) findViewById(android.R.id.custom);
45 * fl.addView(myView, new LayoutParams(MATCH_PARENT, WRAP_CONTENT));
46 * </pre>
47 *
48 * <p>The AlertDialog class takes care of automatically setting
49 * {@link WindowManager.LayoutParams#FLAG_ALT_FOCUSABLE_IM
50 * WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM} for you based on whether
51 * any views in the dialog return true from {@link View#onCheckIsTextEditor()
52 * View.onCheckIsTextEditor()}.  Generally you want this set for a Dialog
53 * without text editors, so that it will be placed on top of the current
54 * input method UI.  You can modify this behavior by forcing the flag to your
55 * desired mode after calling {@link #onCreate}.
56 *
57 * <div class="special reference">
58 * <h3>Developer Guides</h3>
59 * <p>For more information about creating dialogs, read the
60 * <a href="{@docRoot}guide/topics/ui/dialogs.html">Dialogs</a> developer guide.</p>
61 * </div>
62 */
63public class AlertDialog extends AppCompatDialog implements DialogInterface {
64
65    private AlertController mAlert;
66
67    /**
68     * No layout hint.
69     */
70    static final int LAYOUT_HINT_NONE = 0;
71
72    /**
73     * Hint layout to the side.
74     */
75    static final int LAYOUT_HINT_SIDE = 1;
76
77    protected AlertDialog(Context context) {
78        this(context, resolveDialogTheme(context, 0), true);
79    }
80
81    /**
82     * Construct an AlertDialog that uses an explicit theme.  The actual style
83     * that an AlertDialog uses is a private implementation, however you can
84     * here supply either the name of an attribute in the theme from which
85     * to get the dialog's style (such as {@link android.R.attr#alertDialogTheme}.
86     */
87    protected AlertDialog(Context context, int theme) {
88        this(context, theme, true);
89    }
90
91    AlertDialog(Context context, int theme, boolean createThemeContextWrapper) {
92        super(context, resolveDialogTheme(context, theme));
93        mAlert = new AlertController(getContext(), this, getWindow());
94    }
95
96    protected AlertDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
97        super(context, resolveDialogTheme(context, 0));
98        setCancelable(cancelable);
99        setOnCancelListener(cancelListener);
100        mAlert = new AlertController(context, this, getWindow());
101    }
102
103    static int resolveDialogTheme(Context context, int resid) {
104        if (resid >= 0x01000000) {   // start of real resource IDs.
105            return resid;
106        } else {
107            TypedValue outValue = new TypedValue();
108            context.getTheme().resolveAttribute(R.attr.alertDialogTheme, outValue, true);
109            return outValue.resourceId;
110        }
111    }
112
113    /**
114     * Gets one of the buttons used in the dialog. Returns null if the specified
115     * button does not exist or the dialog has not yet been fully created (for
116     * example, via {@link #show()} or {@link #create()}).
117     *
118     * @param whichButton The identifier of the button that should be returned.
119     *                    For example, this can be
120     *                    {@link DialogInterface#BUTTON_POSITIVE}.
121     * @return The button from the dialog, or null if a button does not exist.
122     */
123    public Button getButton(int whichButton) {
124        return mAlert.getButton(whichButton);
125    }
126
127    /**
128     * Gets the list view used in the dialog.
129     *
130     * @return The {@link ListView} from the dialog.
131     */
132    public ListView getListView() {
133        return mAlert.getListView();
134    }
135
136    @Override
137    public void setTitle(CharSequence title) {
138        super.setTitle(title);
139        mAlert.setTitle(title);
140    }
141
142    /**
143     * @see Builder#setCustomTitle(View)
144     */
145    public void setCustomTitle(View customTitleView) {
146        mAlert.setCustomTitle(customTitleView);
147    }
148
149    public void setMessage(CharSequence message) {
150        mAlert.setMessage(message);
151    }
152
153    /**
154     * Set the view to display in that dialog.
155     */
156    public void setView(View view) {
157        mAlert.setView(view);
158    }
159
160    /**
161     * Set the view to display in that dialog, specifying the spacing to appear around that
162     * view.
163     *
164     * @param view              The view to show in the content area of the dialog
165     * @param viewSpacingLeft   Extra space to appear to the left of {@code view}
166     * @param viewSpacingTop    Extra space to appear above {@code view}
167     * @param viewSpacingRight  Extra space to appear to the right of {@code view}
168     * @param viewSpacingBottom Extra space to appear below {@code view}
169     */
170    public void setView(View view, int viewSpacingLeft, int viewSpacingTop, int viewSpacingRight,
171            int viewSpacingBottom) {
172        mAlert.setView(view, viewSpacingLeft, viewSpacingTop, viewSpacingRight, viewSpacingBottom);
173    }
174
175    /**
176     * Internal api to allow hinting for the best button panel layout.
177     *
178     * @hide
179     */
180    void setButtonPanelLayoutHint(int layoutHint) {
181        mAlert.setButtonPanelLayoutHint(layoutHint);
182    }
183
184    /**
185     * Set a message to be sent when a button is pressed. This method has no effect if called
186     * after {@link #show()}.
187     *
188     * @param whichButton Which button to set the message for, can be one of
189     *                    {@link DialogInterface#BUTTON_POSITIVE},
190     *                    {@link DialogInterface#BUTTON_NEGATIVE}, or
191     *                    {@link DialogInterface#BUTTON_NEUTRAL}
192     * @param text        The text to display in positive button.
193     * @param msg         The {@link Message} to be sent when clicked.
194     */
195    public void setButton(int whichButton, CharSequence text, Message msg) {
196        mAlert.setButton(whichButton, text, null, msg);
197    }
198
199    /**
200     * Set a listener to be invoked when the positive button of the dialog is pressed. This method
201     * has no effect if called after {@link #show()}.
202     *
203     * @param whichButton Which button to set the listener on, can be one of
204     *                    {@link DialogInterface#BUTTON_POSITIVE},
205     *                    {@link DialogInterface#BUTTON_NEGATIVE}, or
206     *                    {@link DialogInterface#BUTTON_NEUTRAL}
207     * @param text        The text to display in positive button.
208     * @param listener    The {@link DialogInterface.OnClickListener} to use.
209     */
210    public void setButton(int whichButton, CharSequence text, OnClickListener listener) {
211        mAlert.setButton(whichButton, text, listener, null);
212    }
213
214    /**
215     * Set resId to 0 if you don't want an icon.
216     *
217     * @param resId the resourceId of the drawable to use as the icon or 0
218     *              if you don't want an icon.
219     */
220    public void setIcon(int resId) {
221        mAlert.setIcon(resId);
222    }
223
224    public void setIcon(Drawable icon) {
225        mAlert.setIcon(icon);
226    }
227
228    /**
229     * Set an icon as supplied by a theme attribute. e.g. android.R.attr.alertDialogIcon
230     *
231     * @param attrId ID of a theme attribute that points to a drawable resource.
232     */
233    public void setIconAttribute(int attrId) {
234        TypedValue out = new TypedValue();
235        getContext().getTheme().resolveAttribute(attrId, out, true);
236        mAlert.setIcon(out.resourceId);
237    }
238
239    @Override
240    protected void onCreate(Bundle savedInstanceState) {
241        super.onCreate(savedInstanceState);
242        mAlert.installContent();
243    }
244
245    @Override
246    public boolean onKeyDown(int keyCode, KeyEvent event) {
247        if (mAlert.onKeyDown(keyCode, event)) {
248            return true;
249        }
250        return super.onKeyDown(keyCode, event);
251    }
252
253    @Override
254    public boolean onKeyUp(int keyCode, KeyEvent event) {
255        if (mAlert.onKeyUp(keyCode, event)) {
256            return true;
257        }
258        return super.onKeyUp(keyCode, event);
259    }
260
261    public static class Builder {
262
263        private final AlertController.AlertParams P;
264
265        private int mTheme;
266
267        /**
268         * Constructor using a context for this builder and the {@link AlertDialog} it creates.
269         */
270        public Builder(Context context) {
271            this(context, resolveDialogTheme(context, 0));
272        }
273
274        /**
275         * Constructor using a context and theme for this builder and
276         * the {@link AlertDialog} it creates.  The actual theme
277         * that an AlertDialog uses is a private implementation, however you can
278         * here supply either the name of an attribute in the theme from which
279         * to get the dialog's style (such as {@link android.R.attr#alertDialogTheme}.
280         */
281        public Builder(Context context, int theme) {
282            P = new AlertController.AlertParams(new ContextThemeWrapper(
283                    context, resolveDialogTheme(context, theme)));
284            mTheme = theme;
285        }
286
287        /**
288         * Returns a {@link Context} with the appropriate theme for dialogs created by this
289         * Builder.
290         * Applications should use this Context for obtaining LayoutInflaters for inflating views
291         * that will be used in the resulting dialogs, as it will cause views to be inflated with
292         * the correct theme.
293         *
294         * @return A Context for built Dialogs.
295         */
296        public Context getContext() {
297            return P.mContext;
298        }
299
300        /**
301         * Set the title using the given resource id.
302         *
303         * @return This Builder object to allow for chaining of calls to set methods
304         */
305        public Builder setTitle(int titleId) {
306            P.mTitle = P.mContext.getText(titleId);
307            return this;
308        }
309
310        /**
311         * Set the title displayed in the {@link Dialog}.
312         *
313         * @return This Builder object to allow for chaining of calls to set methods
314         */
315        public Builder setTitle(CharSequence title) {
316            P.mTitle = title;
317            return this;
318        }
319
320        /**
321         * Set the title using the custom view {@code customTitleView}. The
322         * methods {@link #setTitle(int)} and {@link #setIcon(int)} should be
323         * sufficient for most titles, but this is provided if the title needs
324         * more customization. Using this will replace the title and icon set
325         * via the other methods.
326         *
327         * @param customTitleView The custom view to use as the title.
328         * @return This Builder object to allow for chaining of calls to set methods
329         */
330        public Builder setCustomTitle(View customTitleView) {
331            P.mCustomTitleView = customTitleView;
332            return this;
333        }
334
335        /**
336         * Set the message to display using the given resource id.
337         *
338         * @return This Builder object to allow for chaining of calls to set methods
339         */
340        public Builder setMessage(int messageId) {
341            P.mMessage = P.mContext.getText(messageId);
342            return this;
343        }
344
345        /**
346         * Set the message to display.
347         *
348         * @return This Builder object to allow for chaining of calls to set methods
349         */
350        public Builder setMessage(CharSequence message) {
351            P.mMessage = message;
352            return this;
353        }
354
355        /**
356         * Set the resource id of the {@link Drawable} to be used in the title.
357         * <p>
358         * Takes precedence over values set using {@link #setIcon(Drawable)}.
359         *
360         * @return This Builder object to allow for chaining of calls to set methods
361         */
362        public Builder setIcon(int iconId) {
363            P.mIconId = iconId;
364            return this;
365        }
366
367        /**
368         * Set the {@link Drawable} to be used in the title.
369         *
370         * @return This Builder object to allow for chaining of calls to set methods
371         */
372        public Builder setIcon(Drawable icon) {
373            P.mIcon = icon;
374            return this;
375        }
376
377        /**
378         * Set an icon as supplied by a theme attribute. e.g.
379         * {@link android.R.attr#alertDialogIcon}.
380         * <p>
381         * Takes precedence over values set using {@link #setIcon(int)} or
382         * {@link #setIcon(Drawable)}.
383         *
384         * @param attrId ID of a theme attribute that points to a drawable resource.
385         */
386        public Builder setIconAttribute(int attrId) {
387            TypedValue out = new TypedValue();
388            P.mContext.getTheme().resolveAttribute(attrId, out, true);
389            P.mIconId = out.resourceId;
390            return this;
391        }
392
393        /**
394         * Set a listener to be invoked when the positive button of the dialog is pressed.
395         *
396         * @param textId   The resource id of the text to display in the positive button
397         * @param listener The {@link DialogInterface.OnClickListener} to use.
398         * @return This Builder object to allow for chaining of calls to set methods
399         */
400        public Builder setPositiveButton(int textId, final OnClickListener listener) {
401            P.mPositiveButtonText = P.mContext.getText(textId);
402            P.mPositiveButtonListener = listener;
403            return this;
404        }
405
406        /**
407         * Set a listener to be invoked when the positive button of the dialog is pressed.
408         *
409         * @param text     The text to display in the positive button
410         * @param listener The {@link DialogInterface.OnClickListener} to use.
411         * @return This Builder object to allow for chaining of calls to set methods
412         */
413        public Builder setPositiveButton(CharSequence text, final OnClickListener listener) {
414            P.mPositiveButtonText = text;
415            P.mPositiveButtonListener = listener;
416            return this;
417        }
418
419        /**
420         * Set a listener to be invoked when the negative button of the dialog is pressed.
421         *
422         * @param textId   The resource id of the text to display in the negative button
423         * @param listener The {@link DialogInterface.OnClickListener} to use.
424         * @return This Builder object to allow for chaining of calls to set methods
425         */
426        public Builder setNegativeButton(int textId, final OnClickListener listener) {
427            P.mNegativeButtonText = P.mContext.getText(textId);
428            P.mNegativeButtonListener = listener;
429            return this;
430        }
431
432        /**
433         * Set a listener to be invoked when the negative button of the dialog is pressed.
434         *
435         * @param text     The text to display in the negative button
436         * @param listener The {@link DialogInterface.OnClickListener} to use.
437         * @return This Builder object to allow for chaining of calls to set methods
438         */
439        public Builder setNegativeButton(CharSequence text, final OnClickListener listener) {
440            P.mNegativeButtonText = text;
441            P.mNegativeButtonListener = listener;
442            return this;
443        }
444
445        /**
446         * Set a listener to be invoked when the neutral button of the dialog is pressed.
447         *
448         * @param textId   The resource id of the text to display in the neutral button
449         * @param listener The {@link DialogInterface.OnClickListener} to use.
450         * @return This Builder object to allow for chaining of calls to set methods
451         */
452        public Builder setNeutralButton(int textId, final OnClickListener listener) {
453            P.mNeutralButtonText = P.mContext.getText(textId);
454            P.mNeutralButtonListener = listener;
455            return this;
456        }
457
458        /**
459         * Set a listener to be invoked when the neutral button of the dialog is pressed.
460         *
461         * @param text     The text to display in the neutral button
462         * @param listener The {@link DialogInterface.OnClickListener} to use.
463         * @return This Builder object to allow for chaining of calls to set methods
464         */
465        public Builder setNeutralButton(CharSequence text, final OnClickListener listener) {
466            P.mNeutralButtonText = text;
467            P.mNeutralButtonListener = listener;
468            return this;
469        }
470
471        /**
472         * Sets whether the dialog is cancelable or not.  Default is true.
473         *
474         * @return This Builder object to allow for chaining of calls to set methods
475         */
476        public Builder setCancelable(boolean cancelable) {
477            P.mCancelable = cancelable;
478            return this;
479        }
480
481        /**
482         * Sets the callback that will be called if the dialog is canceled.
483         *
484         * <p>Even in a cancelable dialog, the dialog may be dismissed for reasons other than
485         * being canceled or one of the supplied choices being selected.
486         * If you are interested in listening for all cases where the dialog is dismissed
487         * and not just when it is canceled, see
488         * {@link #setOnDismissListener(android.content.DialogInterface.OnDismissListener)
489         * setOnDismissListener}.</p>
490         *
491         * @return This Builder object to allow for chaining of calls to set methods
492         * @see #setCancelable(boolean)
493         * @see #setOnDismissListener(android.content.DialogInterface.OnDismissListener)
494         */
495        public Builder setOnCancelListener(OnCancelListener onCancelListener) {
496            P.mOnCancelListener = onCancelListener;
497            return this;
498        }
499
500        /**
501         * Sets the callback that will be called when the dialog is dismissed for any reason.
502         *
503         * @return This Builder object to allow for chaining of calls to set methods
504         */
505        public Builder setOnDismissListener(OnDismissListener onDismissListener) {
506            P.mOnDismissListener = onDismissListener;
507            return this;
508        }
509
510        /**
511         * Sets the callback that will be called if a key is dispatched to the dialog.
512         *
513         * @return This Builder object to allow for chaining of calls to set methods
514         */
515        public Builder setOnKeyListener(OnKeyListener onKeyListener) {
516            P.mOnKeyListener = onKeyListener;
517            return this;
518        }
519
520        /**
521         * Set a list of items to be displayed in the dialog as the content, you will be notified of
522         * the
523         * selected item via the supplied listener. This should be an array type i.e. R.array.foo
524         *
525         * @return This Builder object to allow for chaining of calls to set methods
526         */
527        public Builder setItems(int itemsId, final OnClickListener listener) {
528            P.mItems = P.mContext.getResources().getTextArray(itemsId);
529            P.mOnClickListener = listener;
530            return this;
531        }
532
533        /**
534         * Set a list of items to be displayed in the dialog as the content, you will be notified of
535         * the
536         * selected item via the supplied listener.
537         *
538         * @return This Builder object to allow for chaining of calls to set methods
539         */
540        public Builder setItems(CharSequence[] items, final OnClickListener listener) {
541            P.mItems = items;
542            P.mOnClickListener = listener;
543            return this;
544        }
545
546        /**
547         * Set a list of items, which are supplied by the given {@link ListAdapter}, to be
548         * displayed in the dialog as the content, you will be notified of the
549         * selected item via the supplied listener.
550         *
551         * @param adapter  The {@link ListAdapter} to supply the list of items
552         * @param listener The listener that will be called when an item is clicked.
553         * @return This Builder object to allow for chaining of calls to set methods
554         */
555        public Builder setAdapter(final ListAdapter adapter, final OnClickListener listener) {
556            P.mAdapter = adapter;
557            P.mOnClickListener = listener;
558            return this;
559        }
560
561        /**
562         * Set a list of items, which are supplied by the given {@link Cursor}, to be
563         * displayed in the dialog as the content, you will be notified of the
564         * selected item via the supplied listener.
565         *
566         * @param cursor      The {@link Cursor} to supply the list of items
567         * @param listener    The listener that will be called when an item is clicked.
568         * @param labelColumn The column name on the cursor containing the string to display
569         *                    in the label.
570         * @return This Builder object to allow for chaining of calls to set methods
571         */
572        public Builder setCursor(final Cursor cursor, final OnClickListener listener,
573                String labelColumn) {
574            P.mCursor = cursor;
575            P.mLabelColumn = labelColumn;
576            P.mOnClickListener = listener;
577            return this;
578        }
579
580        /**
581         * Set a list of items to be displayed in the dialog as the content,
582         * you will be notified of the selected item via the supplied listener.
583         * This should be an array type, e.g. R.array.foo. The list will have
584         * a check mark displayed to the right of the text for each checked
585         * item. Clicking on an item in the list will not dismiss the dialog.
586         * Clicking on a button will dismiss the dialog.
587         *
588         * @param itemsId      the resource id of an array i.e. R.array.foo
589         * @param checkedItems specifies which items are checked. It should be null in which case
590         *                     no
591         *                     items are checked. If non null it must be exactly the same length as
592         *                     the array of
593         *                     items.
594         * @param listener     notified when an item on the list is clicked. The dialog will not be
595         *                     dismissed when an item is clicked. It will only be dismissed if
596         *                     clicked on a
597         *                     button, if no buttons are supplied it's up to the user to dismiss the
598         *                     dialog.
599         * @return This Builder object to allow for chaining of calls to set methods
600         */
601        public Builder setMultiChoiceItems(int itemsId, boolean[] checkedItems,
602                final OnMultiChoiceClickListener listener) {
603            P.mItems = P.mContext.getResources().getTextArray(itemsId);
604            P.mOnCheckboxClickListener = listener;
605            P.mCheckedItems = checkedItems;
606            P.mIsMultiChoice = true;
607            return this;
608        }
609
610        /**
611         * Set a list of items to be displayed in the dialog as the content,
612         * you will be notified of the selected item via the supplied listener.
613         * The list will have a check mark displayed to the right of the text
614         * for each checked item. Clicking on an item in the list will not
615         * dismiss the dialog. Clicking on a button will dismiss the dialog.
616         *
617         * @param items        the text of the items to be displayed in the list.
618         * @param checkedItems specifies which items are checked. It should be null in which case
619         *                     no
620         *                     items are checked. If non null it must be exactly the same length as
621         *                     the array of
622         *                     items.
623         * @param listener     notified when an item on the list is clicked. The dialog will not be
624         *                     dismissed when an item is clicked. It will only be dismissed if
625         *                     clicked on a
626         *                     button, if no buttons are supplied it's up to the user to dismiss the
627         *                     dialog.
628         * @return This Builder object to allow for chaining of calls to set methods
629         */
630        public Builder setMultiChoiceItems(CharSequence[] items, boolean[] checkedItems,
631                final OnMultiChoiceClickListener listener) {
632            P.mItems = items;
633            P.mOnCheckboxClickListener = listener;
634            P.mCheckedItems = checkedItems;
635            P.mIsMultiChoice = true;
636            return this;
637        }
638
639        /**
640         * Set a list of items to be displayed in the dialog as the content,
641         * you will be notified of the selected item via the supplied listener.
642         * The list will have a check mark displayed to the right of the text
643         * for each checked item. Clicking on an item in the list will not
644         * dismiss the dialog. Clicking on a button will dismiss the dialog.
645         *
646         * @param cursor          the cursor used to provide the items.
647         * @param isCheckedColumn specifies the column name on the cursor to use to determine
648         *                        whether a checkbox is checked or not. It must return an integer
649         *                        value where 1
650         *                        means checked and 0 means unchecked.
651         * @param labelColumn     The column name on the cursor containing the string to display in
652         *                        the
653         *                        label.
654         * @param listener        notified when an item on the list is clicked. The dialog will not
655         *                        be
656         *                        dismissed when an item is clicked. It will only be dismissed if
657         *                        clicked on a
658         *                        button, if no buttons are supplied it's up to the user to dismiss
659         *                        the dialog.
660         * @return This Builder object to allow for chaining of calls to set methods
661         */
662        public Builder setMultiChoiceItems(Cursor cursor, String isCheckedColumn,
663                String labelColumn,
664                final OnMultiChoiceClickListener listener) {
665            P.mCursor = cursor;
666            P.mOnCheckboxClickListener = listener;
667            P.mIsCheckedColumn = isCheckedColumn;
668            P.mLabelColumn = labelColumn;
669            P.mIsMultiChoice = true;
670            return this;
671        }
672
673        /**
674         * Set a list of items to be displayed in the dialog as the content, you will be notified
675         * of
676         * the selected item via the supplied listener. This should be an array type i.e.
677         * R.array.foo The list will have a check mark displayed to the right of the text for the
678         * checked item. Clicking on an item in the list will not dismiss the dialog. Clicking on a
679         * button will dismiss the dialog.
680         *
681         * @param itemsId     the resource id of an array i.e. R.array.foo
682         * @param checkedItem specifies which item is checked. If -1 no items are checked.
683         * @param listener    notified when an item on the list is clicked. The dialog will not be
684         *                    dismissed when an item is clicked. It will only be dismissed if
685         *                    clicked on a
686         *                    button, if no buttons are supplied it's up to the user to dismiss the
687         *                    dialog.
688         * @return This Builder object to allow for chaining of calls to set methods
689         */
690        public Builder setSingleChoiceItems(int itemsId, int checkedItem,
691                final OnClickListener listener) {
692            P.mItems = P.mContext.getResources().getTextArray(itemsId);
693            P.mOnClickListener = listener;
694            P.mCheckedItem = checkedItem;
695            P.mIsSingleChoice = true;
696            return this;
697        }
698
699        /**
700         * Set a list of items to be displayed in the dialog as the content, you will be notified
701         * of
702         * the selected item via the supplied listener. The list will have a check mark displayed
703         * to
704         * the right of the text for the checked item. Clicking on an item in the list will not
705         * dismiss the dialog. Clicking on a button will dismiss the dialog.
706         *
707         * @param cursor      the cursor to retrieve the items from.
708         * @param checkedItem specifies which item is checked. If -1 no items are checked.
709         * @param labelColumn The column name on the cursor containing the string to display in the
710         *                    label.
711         * @param listener    notified when an item on the list is clicked. The dialog will not be
712         *                    dismissed when an item is clicked. It will only be dismissed if
713         *                    clicked on a
714         *                    button, if no buttons are supplied it's up to the user to dismiss the
715         *                    dialog.
716         * @return This Builder object to allow for chaining of calls to set methods
717         */
718        public Builder setSingleChoiceItems(Cursor cursor, int checkedItem, String labelColumn,
719                final OnClickListener listener) {
720            P.mCursor = cursor;
721            P.mOnClickListener = listener;
722            P.mCheckedItem = checkedItem;
723            P.mLabelColumn = labelColumn;
724            P.mIsSingleChoice = true;
725            return this;
726        }
727
728        /**
729         * Set a list of items to be displayed in the dialog as the content, you will be notified
730         * of
731         * the selected item via the supplied listener. The list will have a check mark displayed
732         * to
733         * the right of the text for the checked item. Clicking on an item in the list will not
734         * dismiss the dialog. Clicking on a button will dismiss the dialog.
735         *
736         * @param items       the items to be displayed.
737         * @param checkedItem specifies which item is checked. If -1 no items are checked.
738         * @param listener    notified when an item on the list is clicked. The dialog will not be
739         *                    dismissed when an item is clicked. It will only be dismissed if
740         *                    clicked on a
741         *                    button, if no buttons are supplied it's up to the user to dismiss the
742         *                    dialog.
743         * @return This Builder object to allow for chaining of calls to set methods
744         */
745        public Builder setSingleChoiceItems(CharSequence[] items, int checkedItem,
746                final OnClickListener listener) {
747            P.mItems = items;
748            P.mOnClickListener = listener;
749            P.mCheckedItem = checkedItem;
750            P.mIsSingleChoice = true;
751            return this;
752        }
753
754        /**
755         * Set a list of items to be displayed in the dialog as the content, you will be notified
756         * of
757         * the selected item via the supplied listener. The list will have a check mark displayed
758         * to
759         * the right of the text for the checked item. Clicking on an item in the list will not
760         * dismiss the dialog. Clicking on a button will dismiss the dialog.
761         *
762         * @param adapter     The {@link ListAdapter} to supply the list of items
763         * @param checkedItem specifies which item is checked. If -1 no items are checked.
764         * @param listener    notified when an item on the list is clicked. The dialog will not be
765         *                    dismissed when an item is clicked. It will only be dismissed if
766         *                    clicked on a
767         *                    button, if no buttons are supplied it's up to the user to dismiss the
768         *                    dialog.
769         * @return This Builder object to allow for chaining of calls to set methods
770         */
771        public Builder setSingleChoiceItems(ListAdapter adapter, int checkedItem,
772                final OnClickListener listener) {
773            P.mAdapter = adapter;
774            P.mOnClickListener = listener;
775            P.mCheckedItem = checkedItem;
776            P.mIsSingleChoice = true;
777            return this;
778        }
779
780        /**
781         * Sets a listener to be invoked when an item in the list is selected.
782         *
783         * @param listener The listener to be invoked.
784         * @return This Builder object to allow for chaining of calls to set methods
785         * @see AdapterView#setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener)
786         */
787        public Builder setOnItemSelectedListener(
788                final AdapterView.OnItemSelectedListener listener) {
789            P.mOnItemSelectedListener = listener;
790            return this;
791        }
792
793        /**
794         * Set a custom view resource to be the contents of the Dialog. The
795         * resource will be inflated, adding all top-level views to the screen.
796         *
797         * @param layoutResId Resource ID to be inflated.
798         * @return This Builder object to allow for chaining of calls to set
799         * methods
800         */
801        public Builder setView(int layoutResId) {
802            P.mView = null;
803            P.mViewLayoutResId = layoutResId;
804            P.mViewSpacingSpecified = false;
805            return this;
806        }
807
808        /**
809         * Set a custom view to be the contents of the Dialog. If the supplied view is an instance
810         * of a {@link ListView} the light background will be used.
811         *
812         * @param view The view to use as the contents of the Dialog.
813         * @return This Builder object to allow for chaining of calls to set methods
814         */
815        public Builder setView(View view) {
816            P.mView = view;
817            P.mViewLayoutResId = 0;
818            P.mViewSpacingSpecified = false;
819            return this;
820        }
821
822        /**
823         * Set a custom view to be the contents of the Dialog, specifying the
824         * spacing to appear around that view. If the supplied view is an
825         * instance of a {@link ListView} the light background will be used.
826         *
827         * @param view              The view to use as the contents of the Dialog.
828         * @param viewSpacingLeft   Spacing between the left edge of the view and
829         *                          the dialog frame
830         * @param viewSpacingTop    Spacing between the top edge of the view and
831         *                          the dialog frame
832         * @param viewSpacingRight  Spacing between the right edge of the view
833         *                          and the dialog frame
834         * @param viewSpacingBottom Spacing between the bottom edge of the view
835         *                          and the dialog frame
836         * @return This Builder object to allow for chaining of calls to set
837         * methods
838         *
839         *
840         * This is currently hidden because it seems like people should just
841         * be able to put padding around the view.
842         * @hide
843         */
844        public Builder setView(View view, int viewSpacingLeft, int viewSpacingTop,
845                int viewSpacingRight, int viewSpacingBottom) {
846            P.mView = view;
847            P.mViewLayoutResId = 0;
848            P.mViewSpacingSpecified = true;
849            P.mViewSpacingLeft = viewSpacingLeft;
850            P.mViewSpacingTop = viewSpacingTop;
851            P.mViewSpacingRight = viewSpacingRight;
852            P.mViewSpacingBottom = viewSpacingBottom;
853            return this;
854        }
855
856        /**
857         * Sets the Dialog to use the inverse background, regardless of what the
858         * contents is.
859         *
860         * @param useInverseBackground Whether to use the inverse background
861         * @return This Builder object to allow for chaining of calls to set methods
862         */
863        public Builder setInverseBackgroundForced(boolean useInverseBackground) {
864            P.mForceInverseBackground = useInverseBackground;
865            return this;
866        }
867
868        /**
869         * @hide
870         */
871        public Builder setRecycleOnMeasureEnabled(boolean enabled) {
872            P.mRecycleOnMeasure = enabled;
873            return this;
874        }
875
876
877        /**
878         * Creates a {@link AlertDialog} with the arguments supplied to this builder. It does not
879         * {@link Dialog#show()} the dialog. This allows the user to do any extra processing
880         * before displaying the dialog. Use {@link #show()} if you don't have any other processing
881         * to do and want this to be created and displayed.
882         */
883        public AlertDialog create() {
884            final AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false);
885            P.apply(dialog.mAlert);
886            dialog.setCancelable(P.mCancelable);
887            if (P.mCancelable) {
888                dialog.setCanceledOnTouchOutside(true);
889            }
890            dialog.setOnCancelListener(P.mOnCancelListener);
891            dialog.setOnDismissListener(P.mOnDismissListener);
892            if (P.mOnKeyListener != null) {
893                dialog.setOnKeyListener(P.mOnKeyListener);
894            }
895            return dialog;
896        }
897
898        /**
899         * Creates a {@link AlertDialog} with the arguments supplied to this builder and
900         * {@link Dialog#show()}'s the dialog.
901         */
902        public AlertDialog show() {
903            AlertDialog dialog = create();
904            dialog.show();
905            return dialog;
906        }
907    }
908
909}
910