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