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