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