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