Scott Main | b10b48f | 2011-09-13 16:40:52 -0700 | [diff] [blame] | 1 | page.title=Dialogs |
Scott Main | 64461bf | 2013-04-11 19:32:08 -0700 | [diff] [blame] | 2 | page.tags="alertdialog","dialogfragment" |
| 3 | |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 4 | @jd:body |
| 5 | |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 6 | |
| 7 | |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 8 | <div id="qv-wrapper"> |
| 9 | <div id="qv"> |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 10 | <h2>In this document</h2> |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 11 | <ol> |
| 12 | <li><a href="#DialogFragment">Creating a Dialog Fragment</a></li> |
| 13 | <li><a href="#AlertDialog">Building an Alert Dialog</a> |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 14 | <ol> |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 15 | <li><a href="#AddingButtons">Adding buttons</a></li> |
| 16 | <li><a href="#AddingAList">Adding a list</a></li> |
| 17 | <li><a href="#CustomLayout">Creating a Custom Layout</a></li> |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 18 | </ol> |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 19 | </li> |
| 20 | <li><a href="#PassingEvents">Passing Events Back to the Dialog's Host</a></li> |
| 21 | <li><a href="#ShowingADialog">Showing a Dialog</a></li> |
| 22 | <li><a href="#FullscreenDialog">Showing a Dialog Fullscreen or as an Embedded Fragment</a> |
| 23 | <ol> |
| 24 | <li><a href="#ActivityAsDialog">Showing an activity as a dialog on large screens</a></li> |
| 25 | </ol> |
| 26 | </li> |
| 27 | <li><a href="#DismissingADialog">Dismissing a Dialog</a></li> |
| 28 | </ol> |
Scott Main | 18439be | 2010-09-07 17:11:38 -0700 | [diff] [blame] | 29 | |
Scott Main | ec80d7f | 2010-09-24 16:17:27 -0700 | [diff] [blame] | 30 | <h2>Key classes</h2> |
| 31 | <ol> |
Scott Main | 18439be | 2010-09-07 17:11:38 -0700 | [diff] [blame] | 32 | <li>{@link android.app.DialogFragment}</li> |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 33 | <li>{@link android.app.AlertDialog}</li> |
Scott Main | ec80d7f | 2010-09-24 16:17:27 -0700 | [diff] [blame] | 34 | </ol> |
Scott Main | eb5dacd | 2012-01-09 17:36:46 -0800 | [diff] [blame] | 35 | |
| 36 | <h2>See also</h2> |
| 37 | <ol> |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 38 | <li><a href="{@docRoot}design/building-blocks/dialogs.html">Dialogs design guide</a></li> |
| 39 | <li><a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a> (Date/Time dialogs)</li> |
Scott Main | eb5dacd | 2012-01-09 17:36:46 -0800 | [diff] [blame] | 40 | </ol> |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 41 | </div> |
| 42 | </div> |
| 43 | |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 44 | <p>A dialog is a small window that prompts the user to |
| 45 | make a decision or enter additional information. A dialog does not fill the screen and is |
| 46 | normally used for modal events that require users to take an action before they can proceed.</p> |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 47 | |
Scott Main | 91b5ecc | 2012-06-22 13:26:08 -0700 | [diff] [blame] | 48 | <div class="note design"> |
Scott Main | eb5dacd | 2012-01-09 17:36:46 -0800 | [diff] [blame] | 49 | <p><strong>Dialog Design</strong></p> |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 50 | <p>For information about how to design your dialogs, including recommendations |
| 51 | for language, read the <a |
| 52 | href="{@docRoot}design/building-blocks/dialogs.html">Dialogs</a> design guide.</p> |
Scott Main | eb5dacd | 2012-01-09 17:36:46 -0800 | [diff] [blame] | 53 | </div> |
| 54 | |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 55 | <img src="{@docRoot}images/ui/dialogs.png" /> |
| 56 | |
| 57 | <p>The {@link android.app.Dialog} class is the base class for dialogs, but you |
| 58 | should avoid instantiating {@link android.app.Dialog} directly. |
| 59 | Instead, use one of the following subclasses:</p> |
| 60 | <dl> |
| 61 | <dt>{@link android.app.AlertDialog}</dt> |
| 62 | <dd>A dialog that can show a title, up to three buttons, a list of |
| 63 | selectable items, or a custom layout.</dd> |
| 64 | <dt>{@link android.app.DatePickerDialog} or {@link android.app.TimePickerDialog}</dt> |
| 65 | <dd>A dialog with a pre-defined UI that allows the user to select a date or time.</dd> |
| 66 | </dl> |
| 67 | |
| 68 | <div class="sidebox"> |
| 69 | <h2>Avoid ProgressDialog</h2> |
| 70 | <p>Android includes another dialog class called |
| 71 | {@link android.app.ProgressDialog} that shows a dialog with a progress bar. However, if you |
| 72 | need to indicate loading or indeterminate progress, you should instead follow the design |
| 73 | guidelines for <a href="{@docRoot}design/building-blocks/progress.html">Progress & |
| 74 | Activity</a> and use a {@link android.widget.ProgressBar} in your layout.</p> |
| 75 | </div> |
| 76 | |
| 77 | <p>These classes define the style and structure for your dialog, but you should |
| 78 | use a {@link android.support.v4.app.DialogFragment} as a container for your dialog. |
| 79 | The {@link android.support.v4.app.DialogFragment} class provides all the controls you |
| 80 | need to create your dialog and manage its appearance, instead of calling methods |
| 81 | on the {@link android.app.Dialog} object.</p> |
| 82 | |
| 83 | <p>Using {@link android.support.v4.app.DialogFragment} to manage the dialog |
| 84 | ensures that it correctly handles lifecycle events |
| 85 | such as when the user presses the <em>Back</em> button or rotates the screen. The {@link |
| 86 | android.support.v4.app.DialogFragment} class also allows you to reuse the dialog's UI as an |
| 87 | embeddable component in a larger UI, just like a traditional {@link |
| 88 | android.support.v4.app.Fragment} (such as when you want the dialog UI to appear differently |
| 89 | on large and small screens).</p> |
| 90 | |
| 91 | <p>The following sections in this guide describe how to use a {@link |
| 92 | android.support.v4.app.DialogFragment} in combination with an {@link android.app.AlertDialog} |
| 93 | object. If you'd like to create a date or time picker, you should instead read the |
| 94 | <a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a> guide.</p> |
| 95 | |
| 96 | <p class="note"><strong>Note:</strong> |
| 97 | Because the {@link android.app.DialogFragment} class was originally added with |
| 98 | Android 3.0 (API level 11), this document describes how to use the {@link |
| 99 | android.support.v4.app.DialogFragment} class that's provided with the <a |
Scott Main | 4e2c9dc | 2013-07-23 19:35:17 -0700 | [diff] [blame] | 100 | href="{@docRoot}tools/support-library/index.html">Support Library</a>. By adding this library |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 101 | to your app, you can use {@link android.support.v4.app.DialogFragment} and a variety of other |
| 102 | APIs on devices running Android 1.6 or higher. If the minimum version your app supports |
| 103 | is API level 11 or higher, then you can use the framework version of {@link |
| 104 | android.app.DialogFragment}, but be aware that the links in this document are for the support |
| 105 | library APIs. When using the support library, |
| 106 | be sure that you import <code>android.support.v4.app.DialogFragment</code> |
| 107 | class and <em>not</em> <code>android.app.DialogFragment</code>.</p> |
| 108 | |
| 109 | |
| 110 | <h2 id="DialogFragment">Creating a Dialog Fragment</h2> |
| 111 | |
| 112 | <p>You can accomplish a wide variety of dialog designs—including |
| 113 | custom layouts and those described in the <a |
| 114 | href="{@docRoot}design/building-blocks/dialogs.html">Dialogs</a> |
| 115 | design guide—by extending |
| 116 | {@link android.support.v4.app.DialogFragment} and creating a {@link android.app.AlertDialog} |
| 117 | in the {@link android.support.v4.app.DialogFragment#onCreateDialog |
| 118 | onCreateDialog()} callback method.</p> |
| 119 | |
| 120 | <p>For example, here's a basic {@link android.app.AlertDialog} that's managed within |
| 121 | a {@link android.support.v4.app.DialogFragment}:</p> |
| 122 | |
| 123 | <pre> |
Scott Main | 0732210 | 2012-10-17 10:42:54 -0700 | [diff] [blame] | 124 | public class FireMissilesDialogFragment extends DialogFragment { |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 125 | @Override |
| 126 | public Dialog onCreateDialog(Bundle savedInstanceState) { |
| 127 | // Use the Builder class for convenient dialog construction |
| 128 | AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| 129 | builder.setMessage(R.string.dialog_fire_missiles) |
| 130 | .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() { |
| 131 | public void onClick(DialogInterface dialog, int id) { |
| 132 | // FIRE ZE MISSILES! |
| 133 | } |
| 134 | }) |
| 135 | .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { |
| 136 | public void onClick(DialogInterface dialog, int id) { |
| 137 | // User cancelled the dialog |
| 138 | } |
| 139 | }); |
| 140 | // Create the AlertDialog object and return it |
| 141 | return builder.create(); |
| 142 | } |
| 143 | } |
| 144 | </pre> |
| 145 | |
| 146 | <div class="figure" style="width:290px;margin:0 0 0 20px"> |
| 147 | <img src="{@docRoot}images/ui/dialog_buttons.png" alt="" /> |
| 148 | <p class="img-caption"><strong>Figure 1.</strong> |
| 149 | A dialog with a message and two action buttons.</p> |
| 150 | </div> |
| 151 | |
| 152 | <p>Now, when you create an instance of this class and call {@link |
| 153 | android.support.v4.app.DialogFragment#show show()} on that object, the dialog appears as |
| 154 | shown in figure 1.</p> |
| 155 | |
| 156 | <p>The next section describes more about using the {@link android.app.AlertDialog.Builder} |
| 157 | APIs to create the dialog.</p> |
| 158 | |
| 159 | <p>Depending on how complex your dialog is, you can implement a variety of other callback |
| 160 | methods in the {@link android.support.v4.app.DialogFragment}, including all the basic |
| 161 | <a href="{@docRoot}guide/components/fragments.html#Lifecycle">fragment lifecycle methods</a>. |
| 162 | |
| 163 | |
| 164 | |
| 165 | |
| 166 | |
| 167 | <h2 id="AlertDialog">Building an Alert Dialog</h2> |
| 168 | |
| 169 | |
| 170 | <p>The {@link android.app.AlertDialog} class allows you to build a variety of dialog designs and |
| 171 | is often the only dialog class you'll need. |
| 172 | As shown in figure 2, there are three regions of an alert dialog:</p> |
| 173 | |
| 174 | <div class="figure" style="width:311px;margin-top:0"> |
| 175 | <img src="{@docRoot}images/ui/dialogs_regions.png" alt="" style="margin-bottom:0"/> |
| 176 | <p class="img-caption"><strong>Figure 2.</strong> The layout of a dialog.</p> |
| 177 | </div> |
| 178 | |
| 179 | <ol> |
| 180 | <li><b>Title</b> |
| 181 | <p>This is optional and should be used only when the content area |
| 182 | is occupied by a detailed message, a list, or custom layout. If you need to state |
| 183 | a simple message or question (such as the dialog in figure 1), you don't need a title.</li> |
| 184 | <li><b>Content area</b> |
| 185 | <p>This can display a message, a list, or other custom layout.</p></li> |
| 186 | <li><b>Action buttons</b> |
| 187 | <p>There should be no more than three action buttons in a dialog.</p></li> |
| 188 | </ol> |
| 189 | |
| 190 | <p>The {@link android.app.AlertDialog.Builder} |
| 191 | class provides APIs that allow you to create an {@link android.app.AlertDialog} |
| 192 | with these kinds of content, including a custom layout.</p> |
| 193 | |
| 194 | <p>To build an {@link android.app.AlertDialog}:</p> |
| 195 | |
| 196 | <pre> |
| 197 | <b>// 1. Instantiate an {@link android.app.AlertDialog.Builder} with its constructor</b> |
| 198 | AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| 199 | |
| 200 | <b>// 2. Chain together various setter methods to set the dialog characteristics</b> |
| 201 | builder.setMessage(R.string.dialog_message) |
| 202 | .setTitle(R.string.dialog_title); |
| 203 | |
| 204 | <b>// 3. Get the {@link android.app.AlertDialog} from {@link android.app.AlertDialog.Builder#create()}</b> |
| 205 | AlertDialog dialog = builder.create(); |
| 206 | </pre> |
| 207 | |
| 208 | <p>The following topics show how to define various dialog attributes using the |
| 209 | {@link android.app.AlertDialog.Builder} class.</p> |
| 210 | |
| 211 | |
| 212 | |
| 213 | |
| 214 | <h3 id="AddingButtons">Adding buttons</h3> |
| 215 | |
| 216 | <p>To add action buttons like those in figure 2, |
| 217 | call the {@link android.app.AlertDialog.Builder#setPositiveButton setPositiveButton()} and |
| 218 | {@link android.app.AlertDialog.Builder#setNegativeButton setNegativeButton()} methods:</p> |
| 219 | |
| 220 | <pre style="clear:right"> |
| 221 | AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| 222 | // Add the buttons |
| 223 | builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { |
| 224 | public void onClick(DialogInterface dialog, int id) { |
| 225 | // User clicked OK button |
| 226 | } |
| 227 | }); |
| 228 | builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { |
| 229 | public void onClick(DialogInterface dialog, int id) { |
| 230 | // User cancelled the dialog |
| 231 | } |
| 232 | }); |
| 233 | // Set other dialog properties |
| 234 | ... |
| 235 | |
| 236 | // Create the AlertDialog |
| 237 | AlertDialog dialog = builder.create(); |
| 238 | </pre> |
| 239 | |
| 240 | <p>The <code>set...Button()</code> methods require a title for the button (supplied |
| 241 | by a <a href="{@docRoot}guide/topics/resources/string-resource.html">string resource</a>) and a |
| 242 | {@link android.content.DialogInterface.OnClickListener} that defines the action to take |
| 243 | when the user presses the button.</p> |
| 244 | |
| 245 | <p>There are three different action buttons you can add:</p> |
| 246 | <dl> |
| 247 | <dt>Positive</dt> |
| 248 | <dd>You should use this to accept and continue with the action (the "OK" action).</dd> |
| 249 | <dt>Negative</dt> |
| 250 | <dd>You should use this to cancel the action.</dd> |
| 251 | <dt>Neutral</dt> |
| 252 | <dd>You should use this when the user may not want to proceed with the action, |
| 253 | but doesn't necessarily want to cancel. It appears between the positive and negative |
| 254 | buttons. For example, the action might be "Remind me later."</dd> |
| 255 | </dl> |
| 256 | |
| 257 | <p>You can add only one of each button type to an {@link |
| 258 | android.app.AlertDialog}. That is, you cannot have more than one "positive" button.</p> |
| 259 | |
| 260 | |
| 261 | |
| 262 | <div class="figure" style="width:290px;margin:0 0 0 40px"> |
| 263 | <img src="{@docRoot}images/ui/dialog_list.png" alt="" /> |
| 264 | <p class="img-caption"><strong>Figure 3.</strong> |
| 265 | A dialog with a title and list.</p> |
| 266 | </div> |
| 267 | |
| 268 | <h3 id="AddingAList">Adding a list</h3> |
| 269 | |
| 270 | <p>There are three kinds of lists available with the {@link android.app.AlertDialog} APIs:</p> |
| 271 | <ul> |
| 272 | <li>A traditional single-choice list</li> |
| 273 | <li>A persistent single-choice list (radio buttons)</li> |
| 274 | <li>A persistent multiple-choice list (checkboxes)</li> |
| 275 | </ul> |
| 276 | |
| 277 | <p>To create a single-choice list like the one in figure 3, |
| 278 | use the {@link android.app.AlertDialog.Builder#setItems setItems()} method:</p> |
| 279 | |
| 280 | <pre style="clear:right"> |
| 281 | @Override |
| 282 | public Dialog onCreateDialog(Bundle savedInstanceState) { |
| 283 | AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
Ricardo Cervera | 7a8acfa | 2014-01-13 16:44:19 -0800 | [diff] [blame] | 284 | builder.setTitle(R.string.pick_color) |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 285 | .setItems(R.array.colors_array, new DialogInterface.OnClickListener() { |
| 286 | public void onClick(DialogInterface dialog, int which) { |
| 287 | // The 'which' argument contains the index position |
| 288 | // of the selected item |
| 289 | } |
| 290 | }); |
| 291 | return builder.create(); |
| 292 | } |
| 293 | </pre> |
| 294 | |
| 295 | <p>Because the list appears in the dialog's content area, |
| 296 | the dialog cannot show both a message and a list and you should set a title for the |
| 297 | dialog with {@link android.app.AlertDialog.Builder#setTitle setTitle()}. |
| 298 | To specify the items for the list, call {@link |
| 299 | android.app.AlertDialog.Builder#setItems setItems()}, passing an array. |
| 300 | Alternatively, you can specify a list using {@link |
| 301 | android.app.AlertDialog.Builder#setAdapter setAdapter()}. This allows you to back the list |
| 302 | with dynamic data (such as from a database) using a {@link android.widget.ListAdapter}.</p> |
| 303 | |
| 304 | <p>If you choose to back your list with a {@link android.widget.ListAdapter}, |
| 305 | always use a {@link android.support.v4.content.Loader} so that the content loads |
| 306 | asynchronously. This is described further in |
| 307 | <a href="{@docRoot}guide/topics/ui/declaring-layout.html#AdapterViews">Building Layouts |
| 308 | with an Adapter</a> and the <a href="{@docRoot}guide/components/loaders.html">Loaders</a> |
| 309 | guide.</p> |
| 310 | |
| 311 | <p class="note"><strong>Note:</strong> By default, touching a list item dismisses the dialog, |
| 312 | unless you're using one of the following persistent choice lists.</p> |
| 313 | |
| 314 | <div class="figure" style="width:290px;margin:-30px 0 0 40px"> |
| 315 | <img src="{@docRoot}images/ui/dialog_checkboxes.png" /> |
| 316 | <p class="img-caption"><strong>Figure 4.</strong> |
| 317 | A list of multiple-choice items.</p> |
| 318 | </div> |
| 319 | |
| 320 | |
| 321 | <h4 id="Checkboxes">Adding a persistent multiple-choice or single-choice list</h4> |
| 322 | |
| 323 | <p>To add a list of multiple-choice items (checkboxes) or |
| 324 | single-choice items (radio buttons), use the |
| 325 | {@link android.app.AlertDialog.Builder#setMultiChoiceItems(Cursor,String,String, |
| 326 | DialogInterface.OnMultiChoiceClickListener) setMultiChoiceItems()} or |
| 327 | {@link android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) |
| 328 | setSingleChoiceItems()} methods, respectively.</p> |
| 329 | |
| 330 | <p>For example, here's how you can create a multiple-choice list like the |
| 331 | one shown in figure 4 that saves the selected |
| 332 | items in an {@link java.util.ArrayList}:</p> |
| 333 | |
| 334 | <pre style="clear:right"> |
| 335 | @Override |
| 336 | public Dialog onCreateDialog(Bundle savedInstanceState) { |
| 337 | mSelectedItems = new ArrayList(); // Where we track the selected items |
| 338 | AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| 339 | // Set the dialog title |
| 340 | builder.setTitle(R.string.pick_toppings) |
| 341 | // Specify the list array, the items to be selected by default (null for none), |
| 342 | // and the listener through which to receive callbacks when items are selected |
| 343 | .setMultiChoiceItems(R.array.toppings, null, |
| 344 | new DialogInterface.OnMultiChoiceClickListener() { |
| 345 | @Override |
| 346 | public void onClick(DialogInterface dialog, int which, |
| 347 | boolean isChecked) { |
| 348 | if (isChecked) { |
| 349 | // If the user checked the item, add it to the selected items |
| 350 | mSelectedItems.add(which); |
| 351 | } else if (mSelectedItems.contains(which)) { |
| 352 | // Else, if the item is already in the array, remove it |
| 353 | mSelectedItems.remove(Integer.valueOf(which)); |
| 354 | } |
| 355 | } |
| 356 | }) |
| 357 | // Set the action buttons |
| 358 | .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { |
| 359 | @Override |
| 360 | public void onClick(DialogInterface dialog, int id) { |
| 361 | // User clicked OK, so save the mSelectedItems results somewhere |
| 362 | // or return them to the component that opened the dialog |
| 363 | ... |
| 364 | } |
| 365 | }) |
| 366 | .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { |
| 367 | @Override |
| 368 | public void onClick(DialogInterface dialog, int id) { |
| 369 | ... |
| 370 | } |
| 371 | }); |
| 372 | |
| 373 | return builder.create(); |
| 374 | } |
| 375 | </pre> |
| 376 | |
| 377 | <p>Although both a traditional list and a list with radio buttons |
| 378 | provide a "single choice" action, you should use {@link |
| 379 | android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) |
| 380 | setSingleChoiceItems()} if you want to persist the user's choice. |
| 381 | That is, if opening the dialog again later should indicate what the user's current choice is, |
| 382 | then you create a list with radio buttons.</p> |
| 383 | |
| 384 | |
| 385 | |
| 386 | |
| 387 | |
| 388 | <h3 id="CustomLayout">Creating a Custom Layout</h3> |
| 389 | |
| 390 | <div class="figure" style="width:290px;margin:-30px 0 0 40px"> |
| 391 | <img src="{@docRoot}images/ui/dialog_custom.png" alt="" /> |
| 392 | <p class="img-caption"><strong>Figure 5.</strong> A custom dialog layout.</p> |
| 393 | </div> |
| 394 | |
| 395 | <p>If you want a custom layout in a dialog, create a layout and add it to an |
| 396 | {@link android.app.AlertDialog} by calling {@link |
| 397 | android.app.AlertDialog.Builder#setView setView()} on your {@link |
| 398 | android.app.AlertDialog.Builder} object.</p> |
| 399 | |
| 400 | <p>By default, the custom layout fills the dialog window, but you can still |
| 401 | use {@link android.app.AlertDialog.Builder} methods to add buttons and a title.</p> |
| 402 | |
| 403 | <p>For example, here's the layout file for the dialog in Figure 5:</p> |
| 404 | |
| 405 | <p style="clear:right" class="code-caption">res/layout/dialog_signin.xml</p> |
| 406 | <pre> |
| 407 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
| 408 | android:orientation="vertical" |
| 409 | android:layout_width="wrap_content" |
| 410 | android:layout_height="wrap_content"> |
| 411 | <ImageView |
| 412 | android:src="@drawable/header_logo" |
| 413 | android:layout_width="match_parent" |
| 414 | android:layout_height="64dp" |
| 415 | android:scaleType="center" |
| 416 | android:background="#FFFFBB33" |
| 417 | android:contentDescription="@string/app_name" /> |
| 418 | <EditText |
| 419 | android:id="@+id/username" |
| 420 | android:inputType="textEmailAddress" |
| 421 | android:layout_width="match_parent" |
| 422 | android:layout_height="wrap_content" |
| 423 | android:layout_marginTop="16dp" |
| 424 | android:layout_marginLeft="4dp" |
| 425 | android:layout_marginRight="4dp" |
| 426 | android:layout_marginBottom="4dp" |
| 427 | android:hint="@string/username" /> |
| 428 | <EditText |
| 429 | android:id="@+id/password" |
| 430 | android:inputType="textPassword" |
| 431 | android:layout_width="match_parent" |
| 432 | android:layout_height="wrap_content" |
| 433 | android:layout_marginTop="4dp" |
| 434 | android:layout_marginLeft="4dp" |
| 435 | android:layout_marginRight="4dp" |
| 436 | android:layout_marginBottom="16dp" |
| 437 | android:fontFamily="sans-serif" |
| 438 | android:hint="@string/password"/> |
| 439 | </LinearLayout> |
| 440 | </pre> |
| 441 | |
| 442 | <p class="note"><strong>Tip:</strong> By default, when you set an {@link android.widget.EditText} |
| 443 | element to use the {@code "textPassword"} input type, the font family is set to monospace, so |
| 444 | you should change its font family to {@code "sans-serif"} so that both text fields use |
| 445 | a matching font style.</p> |
| 446 | |
| 447 | <p>To inflate the layout in your {@link android.support.v4.app.DialogFragment}, |
| 448 | get a {@link android.view.LayoutInflater} with |
| 449 | {@link android.app.Activity#getLayoutInflater()} and call |
| 450 | {@link android.view.LayoutInflater#inflate inflate()}, where the first parameter |
| 451 | is the layout resource ID and the second parameter is a parent view for the layout. |
| 452 | You can then call {@link android.app.AlertDialog#setView setView()} |
| 453 | to place the layout in the dialog.</p> |
| 454 | |
| 455 | <pre> |
| 456 | @Override |
| 457 | public Dialog onCreateDialog(Bundle savedInstanceState) { |
| 458 | AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| 459 | // Get the layout inflater |
| 460 | LayoutInflater inflater = getActivity().getLayoutInflater(); |
| 461 | |
| 462 | // Inflate and set the layout for the dialog |
| 463 | // Pass null as the parent view because its going in the dialog layout |
| 464 | builder.setView(inflater.inflate(R.layout.dialog_signin, null)) |
| 465 | // Add action buttons |
| 466 | .setPositiveButton(R.string.signin, new DialogInterface.OnClickListener() { |
| 467 | @Override |
| 468 | public void onClick(DialogInterface dialog, int id) { |
| 469 | // sign in the user ... |
| 470 | } |
| 471 | }) |
| 472 | .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { |
| 473 | public void onClick(DialogInterface dialog, int id) { |
Scott Main | 0732210 | 2012-10-17 10:42:54 -0700 | [diff] [blame] | 474 | LoginDialogFragment.this.getDialog().cancel(); |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 475 | } |
| 476 | }); |
| 477 | return builder.create(); |
| 478 | } |
| 479 | </pre> |
| 480 | |
| 481 | <div class="note"> |
| 482 | <p><strong>Tip:</strong> If you want a custom dialog, |
| 483 | you can instead display an {@link android.app.Activity} as a dialog |
| 484 | instead of using the {@link android.app.Dialog} APIs. Simply create an activity and set its theme to |
| 485 | {@link android.R.style#Theme_Holo_Dialog Theme.Holo.Dialog} |
| 486 | in the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code |
| 487 | <activity>}</a> manifest element:</p> |
| 488 | |
| 489 | <pre> |
| 490 | <activity android:theme="@android:style/Theme.Holo.Dialog" > |
| 491 | </pre> |
| 492 | <p>That's it. The activity now displays in a dialog window instead of fullscreen.</p> |
| 493 | </div> |
| 494 | |
| 495 | |
| 496 | |
| 497 | <h2 id="PassingEvents">Passing Events Back to the Dialog's Host</h2> |
| 498 | |
| 499 | <p>When the user touches one of the dialog's action buttons or selects an item from its list, |
| 500 | your {@link android.support.v4.app.DialogFragment} might perform the necessary |
| 501 | action itself, but often you'll want to deliver the event to the activity or fragment that |
Scott Main | 0732210 | 2012-10-17 10:42:54 -0700 | [diff] [blame] | 502 | opened the dialog. To do this, define an interface with a method for each type of click event. |
| 503 | Then implement that interface in the host component that will |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 504 | receive the action events from the dialog.</p> |
| 505 | |
| 506 | <p>For example, here's a {@link android.support.v4.app.DialogFragment} that defines an |
| 507 | interface through which it delivers the events back to the host activity:</p> |
| 508 | |
| 509 | <pre> |
Scott Main | 0732210 | 2012-10-17 10:42:54 -0700 | [diff] [blame] | 510 | public class NoticeDialogFragment extends DialogFragment { |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 511 | |
| 512 | /* The activity that creates an instance of this dialog fragment must |
| 513 | * implement this interface in order to receive event callbacks. |
| 514 | * Each method passes the DialogFragment in case the host needs to query it. */ |
| 515 | public interface NoticeDialogListener { |
| 516 | public void onDialogPositiveClick(DialogFragment dialog); |
| 517 | public void onDialogNegativeClick(DialogFragment dialog); |
| 518 | } |
| 519 | |
| 520 | // Use this instance of the interface to deliver action events |
Scott Main | 0732210 | 2012-10-17 10:42:54 -0700 | [diff] [blame] | 521 | NoticeDialogListener mListener; |
| 522 | |
| 523 | // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener |
| 524 | @Override |
| 525 | public void onAttach(Activity activity) { |
| 526 | super.onAttach(activity); |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 527 | // Verify that the host activity implements the callback interface |
| 528 | try { |
Scott Main | 0732210 | 2012-10-17 10:42:54 -0700 | [diff] [blame] | 529 | // Instantiate the NoticeDialogListener so we can send events to the host |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 530 | mListener = (NoticeDialogListener) activity; |
| 531 | } catch (ClassCastException e) { |
| 532 | // The activity doesn't implement the interface, throw exception |
| 533 | throw new ClassCastException(activity.toString() |
| 534 | + " must implement NoticeDialogListener"); |
| 535 | } |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 536 | } |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 537 | ... |
| 538 | } |
| 539 | </pre> |
| 540 | |
Scott Main | 0732210 | 2012-10-17 10:42:54 -0700 | [diff] [blame] | 541 | <p>The activity hosting the dialog creates an instance of the dialog |
| 542 | with the dialog fragment's constructor and receives the dialog's |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 543 | events through an implementation of the {@code NoticeDialogListener} interface:</p> |
| 544 | |
| 545 | <pre> |
| 546 | public class MainActivity extends FragmentActivity |
Scott Main | 0732210 | 2012-10-17 10:42:54 -0700 | [diff] [blame] | 547 | implements NoticeDialogFragment.NoticeDialogListener{ |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 548 | ... |
| 549 | |
| 550 | public void showNoticeDialog() { |
| 551 | // Create an instance of the dialog fragment and show it |
Scott Main | 0732210 | 2012-10-17 10:42:54 -0700 | [diff] [blame] | 552 | DialogFragment dialog = new NoticeDialogFragment(); |
| 553 | dialog.show(getSupportFragmentManager(), "NoticeDialogFragment"); |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 554 | } |
| 555 | |
Scott Main | 0732210 | 2012-10-17 10:42:54 -0700 | [diff] [blame] | 556 | // The dialog fragment receives a reference to this Activity through the |
| 557 | // Fragment.onAttach() callback, which it uses to call the following methods |
| 558 | // defined by the NoticeDialogFragment.NoticeDialogListener interface |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 559 | @Override |
| 560 | public void onDialogPositiveClick(DialogFragment dialog) { |
| 561 | // User touched the dialog's positive button |
| 562 | ... |
| 563 | } |
| 564 | |
| 565 | @Override |
| 566 | public void onDialogNegativeClick(DialogFragment dialog) { |
| 567 | // User touched the dialog's negative button |
| 568 | ... |
| 569 | } |
| 570 | } |
| 571 | </pre> |
| 572 | |
| 573 | <p>Because the host activity implements the {@code NoticeDialogListener}—which is |
Scott Main | 0732210 | 2012-10-17 10:42:54 -0700 | [diff] [blame] | 574 | enforced by the {@link android.support.v4.app.Fragment#onAttach onAttach()} |
| 575 | callback method shown above—the dialog fragment can use the |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 576 | interface callback methods to deliver click events to the activity:</p> |
| 577 | |
| 578 | <pre> |
Scott Main | 0732210 | 2012-10-17 10:42:54 -0700 | [diff] [blame] | 579 | public class NoticeDialogFragment extends DialogFragment { |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 580 | ... |
| 581 | |
| 582 | @Override |
| 583 | public Dialog onCreateDialog(Bundle savedInstanceState) { |
| 584 | // Build the dialog and set up the button click handlers |
| 585 | AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| 586 | builder.setMessage(R.string.dialog_fire_missiles) |
| 587 | .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() { |
| 588 | public void onClick(DialogInterface dialog, int id) { |
| 589 | // Send the positive button event back to the host activity |
Scott Main | 0732210 | 2012-10-17 10:42:54 -0700 | [diff] [blame] | 590 | mListener.onDialogPositiveClick(NoticeDialogFragment.this); |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 591 | } |
| 592 | }) |
| 593 | .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { |
| 594 | public void onClick(DialogInterface dialog, int id) { |
| 595 | // Send the negative button event back to the host activity |
David Friedman | 2e7c8e9 | 2013-09-26 14:28:51 -0700 | [diff] [blame] | 596 | mListener.onDialogNegativeClick(NoticeDialogFragment.this); |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 597 | } |
| 598 | }); |
| 599 | return builder.create(); |
| 600 | } |
| 601 | } |
| 602 | </pre> |
| 603 | |
| 604 | |
| 605 | |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 606 | <h2 id="ShowingADialog">Showing a Dialog</h2> |
| 607 | |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 608 | <p>When you want to show your dialog, create an instance of your {@link |
| 609 | android.support.v4.app.DialogFragment} and call {@link android.support.v4.app.DialogFragment#show |
| 610 | show()}, passing the {@link android.support.v4.app.FragmentManager} and a tag name |
| 611 | for the dialog fragment.</p> |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 612 | |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 613 | <p>You can get the {@link android.support.v4.app.FragmentManager} by calling |
| 614 | {@link android.support.v4.app.FragmentActivity#getSupportFragmentManager()} from |
| 615 | the {@link android.support.v4.app.FragmentActivity} or {@link |
| 616 | android.support.v4.app.Fragment#getFragmentManager()} from a {@link |
| 617 | android.support.v4.app.Fragment}. For example:</p> |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 618 | |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 619 | <pre> |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 620 | public void confirmFireMissiles() { |
Scott Main | 0732210 | 2012-10-17 10:42:54 -0700 | [diff] [blame] | 621 | DialogFragment newFragment = new FireMissilesDialogFragment(); |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 622 | newFragment.show(getSupportFragmentManager(), "missiles"); |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 623 | } |
| 624 | </pre> |
| 625 | |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 626 | <p>The second argument, {@code "missiles"}, is a unique tag name that the system uses to save |
| 627 | and restore the fragment state when necessary. The tag also allows you to get a handle to |
| 628 | the fragment by calling {@link android.support.v4.app.FragmentManager#findFragmentByTag |
| 629 | findFragmentByTag()}.</p> |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 630 | |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 631 | |
| 632 | |
| 633 | |
| 634 | <h2 id="FullscreenDialog">Showing a Dialog Fullscreen or as an Embedded Fragment</h2> |
| 635 | |
| 636 | <p>You might have a UI design in which you want a piece of the UI to appear as a dialog in some |
| 637 | situations, but as a full screen or embedded fragment in others (perhaps depending on whether |
| 638 | the device is a large screen or small screen). The {@link android.support.v4.app.DialogFragment} |
| 639 | class offers you this flexibility because it can still behave as an embeddable {@link |
| 640 | android.support.v4.app.Fragment}.</p> |
| 641 | |
| 642 | <p>However, you cannot use {@link android.app.AlertDialog.Builder AlertDialog.Builder} |
| 643 | or other {@link android.app.Dialog} objects to build the dialog in this case. If |
| 644 | you want the {@link android.support.v4.app.DialogFragment} to be |
| 645 | embeddable, you must define the dialog's UI in a layout, then load the layout in the |
| 646 | {@link android.support.v4.app.DialogFragment#onCreateView |
| 647 | onCreateView()} callback.</p> |
| 648 | |
| 649 | <p>Here's an example {@link android.support.v4.app.DialogFragment} that can appear as either a |
| 650 | dialog or an embeddable fragment (using a layout named <code>purchase_items.xml</code>):</p> |
| 651 | |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 652 | <pre> |
Scott Main | 0732210 | 2012-10-17 10:42:54 -0700 | [diff] [blame] | 653 | public class CustomDialogFragment extends DialogFragment { |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 654 | /** The system calls this to get the DialogFragment's layout, regardless |
| 655 | of whether it's being displayed as a dialog or an embedded fragment. */ |
| 656 | @Override |
| 657 | public View onCreateView(LayoutInflater inflater, ViewGroup container, |
| 658 | Bundle savedInstanceState) { |
| 659 | // Inflate the layout to use as dialog or embedded fragment |
| 660 | return inflater.inflate(R.layout.purchase_items, container, false); |
| 661 | } |
| 662 | |
| 663 | /** The system calls this only when creating the layout in a dialog. */ |
| 664 | @Override |
| 665 | public Dialog onCreateDialog(Bundle savedInstanceState) { |
| 666 | // The only reason you might override this method when using onCreateView() is |
| 667 | // to modify any dialog characteristics. For example, the dialog includes a |
| 668 | // title by default, but your custom layout might not need it. So here you can |
| 669 | // remove the dialog title, but you must call the superclass to get the Dialog. |
| 670 | Dialog dialog = super.onCreateDialog(savedInstanceState); |
| 671 | dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); |
| 672 | return dialog; |
| 673 | } |
| 674 | } |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 675 | </pre> |
| 676 | |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 677 | <p>And here's some code that decides whether to show the fragment as a dialog |
| 678 | or a fullscreen UI, based on the screen size:</p> |
| 679 | |
| 680 | <pre> |
| 681 | public void showDialog() { |
| 682 | FragmentManager fragmentManager = getSupportFragmentManager(); |
Scott Main | 0732210 | 2012-10-17 10:42:54 -0700 | [diff] [blame] | 683 | CustomDialogFragment newFragment = new CustomDialogFragment(); |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 684 | |
| 685 | if (mIsLargeLayout) { |
| 686 | // The device is using a large layout, so show the fragment as a dialog |
| 687 | newFragment.show(fragmentManager, "dialog"); |
| 688 | } else { |
| 689 | // The device is smaller, so show the fragment fullscreen |
| 690 | FragmentTransaction transaction = fragmentManager.beginTransaction(); |
| 691 | // For a little polish, specify a transition animation |
| 692 | transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); |
| 693 | // To make it fullscreen, use the 'content' root view as the container |
| 694 | // for the fragment, which is always the root view for the activity |
| 695 | transaction.add(android.R.id.content, newFragment) |
| 696 | .addToBackStack(null).commit(); |
| 697 | } |
| 698 | } |
| 699 | </pre> |
| 700 | |
| 701 | <p>For more information about performing fragment transactions, see the |
| 702 | <a href="{@docRoot}guide/components/fragments.html">Fragments</a> guide.</p> |
| 703 | |
| 704 | <p>In this example, the <code>mIsLargeLayout</code> boolean specifies whether the current device |
| 705 | should use the app's large layout design (and thus show this fragment as a dialog, rather |
| 706 | than fullscreen). The best way to set this kind of boolean is to declare a |
| 707 | <a href="{@docRoot}guide/topics/resources/more-resources.html#Bool">bool resource value</a> |
| 708 | with an <a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources" |
| 709 | >alternative resource</a> value for different screen sizes. For example, here are two |
| 710 | versions of the bool resource for different screen sizes:</p> |
| 711 | |
| 712 | <p class="code-caption">res/values/bools.xml</p> |
| 713 | <pre> |
| 714 | <!-- Default boolean values --> |
| 715 | <resources> |
| 716 | <bool name="large_layout">false</bool> |
| 717 | </resources> |
| 718 | </pre> |
| 719 | |
| 720 | <p class="code-caption">res/values-large/bools.xml</p> |
| 721 | <pre> |
| 722 | <!-- Large screen boolean values --> |
| 723 | <resources> |
| 724 | <bool name="large_layout">true</bool> |
| 725 | </resources> |
| 726 | </pre> |
| 727 | |
| 728 | <p>Then you can initialize the {@code mIsLargeLayout} value during the activity's |
| 729 | {@link android.app.Activity#onCreate onCreate()} method:</p> |
| 730 | |
| 731 | <pre> |
| 732 | boolean mIsLargeLayout; |
| 733 | |
| 734 | @Override |
| 735 | public void onCreate(Bundle savedInstanceState) { |
| 736 | super.onCreate(savedInstanceState); |
| 737 | setContentView(R.layout.activity_main); |
| 738 | |
| 739 | mIsLargeLayout = getResources().getBoolean(R.bool.large_layout); |
| 740 | } |
| 741 | </pre> |
| 742 | |
| 743 | |
| 744 | |
| 745 | <h3 id="ActivityAsDialog">Showing an activity as a dialog on large screens</h3> |
| 746 | |
| 747 | <p>Instead of showing a dialog as a fullscreen UI when on small screens, you can accomplish |
| 748 | the same result by showing an {@link android.app.Activity} as a dialog when on |
| 749 | large screens. Which approach you choose depends on your app design, but |
| 750 | showing an activity as a dialog is often useful when your app is already designed for small |
| 751 | screens and you'd like to improve the experience on tablets by showing a short-lived activity |
| 752 | as a dialog.</p> |
| 753 | |
| 754 | <p>To show an activity as a dialog only when on large screens, |
| 755 | apply the {@link android.R.style#Theme_Holo_DialogWhenLarge Theme.Holo.DialogWhenLarge} |
| 756 | theme to the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code |
| 757 | <activity>}</a> manifest element:</p> |
| 758 | |
| 759 | <pre> |
| 760 | <activity android:theme="@android:style/Theme.Holo.DialogWhenLarge" > |
| 761 | </pre> |
| 762 | |
| 763 | <p>For more information about styling your activities with themes, see the <a |
| 764 | href="{@docRoot}guide/topics/ui/themes.html">Styles and Themes</a> guide.</p> |
| 765 | |
| 766 | |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 767 | |
| 768 | <h2 id="DismissingADialog">Dismissing a Dialog</h2> |
| 769 | |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 770 | <p>When the user touches any of the action buttons created with an |
| 771 | {@link android.app.AlertDialog.Builder}, the system dismisses the dialog for you.</p> |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 772 | |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 773 | <p>The system also dismisses the dialog when the user touches an item in a dialog list, except |
| 774 | when the list uses radio buttons or checkboxes. Otherwise, you can manually dismiss your dialog |
| 775 | by calling {@link android.support.v4.app.DialogFragment#dismiss()} on your {@link |
| 776 | android.support.v4.app.DialogFragment}.</p> |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 777 | |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 778 | <p>In case you need to perform certain |
| 779 | actions when the dialog goes away, you can implement the {@link |
| 780 | android.support.v4.app.DialogFragment#onDismiss onDismiss()} method in your {@link |
| 781 | android.support.v4.app.DialogFragment}.</p> |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 782 | |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 783 | <p>You can also <em>cancel</em> a dialog. This is a special event that indicates the user |
| 784 | explicitly left the dialog without completing the task. This occurs if the user presses the |
| 785 | <em>Back</em> button, touches the screen outside the dialog area, |
| 786 | or if you explicitly call {@link android.app.Dialog#cancel()} on the {@link |
| 787 | android.app.Dialog} (such as in response to a "Cancel" button in the dialog).</p> |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 788 | |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 789 | <p>As shown in the example above, you can respond to the cancel event by implementing |
| 790 | {@link android.support.v4.app.DialogFragment#onCancel onCancel()} in your {@link |
| 791 | android.support.v4.app.DialogFragment} class.</p> |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 792 | |
Scott Main | db705ef | 2012-09-11 20:47:48 -0700 | [diff] [blame] | 793 | <p class="note"><strong>Note:</strong> The system calls |
| 794 | {@link android.support.v4.app.DialogFragment#onDismiss onDismiss()} upon each event that |
| 795 | invokes the {@link android.support.v4.app.DialogFragment#onCancel onCancel()} callback. However, |
| 796 | if you call {@link android.app.Dialog#dismiss Dialog.dismiss()} or {@link |
| 797 | android.support.v4.app.DialogFragment#dismiss DialogFragment.dismiss()}, |
| 798 | the system calls {@link android.support.v4.app.DialogFragment#onDismiss onDismiss()} <em>but |
| 799 | not</em> {@link android.support.v4.app.DialogFragment#onCancel onCancel()}. So you should generally |
| 800 | call {@link android.support.v4.app.DialogFragment#dismiss dismiss()} when the user presses the |
| 801 | <em>positive</em> button in your dialog in order to remove the dialog from view.</p> |
Scott Main | ce878be | 2009-04-26 15:51:58 -0700 | [diff] [blame] | 802 | |
| 803 | |