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