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