Home | History | Annotate | Download | only in ui
      1 page.title=Dialogs
      2 page.tags=alertdialog,dialogfragment
      3 
      4 @jd:body
      5 
      6 
      7 
      8 <div id="qv-wrapper">
      9   <div id="qv">
     10     <h2>In this document</h2>
     11 <ol>
     12   <li><a href="#DialogFragment">Creating a Dialog Fragment</a></li>
     13   <li><a href="#AlertDialog">Building an Alert Dialog</a>
     14     <ol>
     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>
     18     </ol>
     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>
     29 
     30     <h2>Key classes</h2>
     31     <ol>
     32       <li>{@link android.app.DialogFragment}</li>
     33       <li>{@link android.app.AlertDialog}</li>
     34     </ol>
     35     
     36     <h2>See also</h2>
     37     <ol>
     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>
     40     </ol>
     41   </div>
     42 </div>
     43 
     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>
     47 
     48 <div class="note design">
     49 <p><strong>Dialog Design</strong></p>
     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>
     53 </div>
     54 
     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 &amp;
     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
    100 href="{@docRoot}tools/support-library/index.html">Support Library</a>. By adding this library
    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&mdash;including
    113 custom layouts and those described in the <a
    114 href="{@docRoot}design/building-blocks/dialogs.html">Dialogs</a>
    115 design guide&mdash;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>
    124 public class FireMissilesDialogFragment extends DialogFragment {
    125     &#64;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 &#64;Override
    282 public Dialog onCreateDialog(Bundle savedInstanceState) {
    283     AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    284     builder.setTitle(R.string.pick_color)
    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 &#64;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                &#64;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                &#64;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                &#64;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 &lt;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     &lt;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     &lt;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     &lt;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 &lt;/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 &#64;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                &#64;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) {
    474                    LoginDialogFragment.this.getDialog().cancel();
    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 &lt;activity&gt;}</a> manifest element:</p>
    488 
    489 <pre>
    490 &lt;activity android:theme="&#64;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
    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
    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>
    510 public class NoticeDialogFragment extends DialogFragment {
    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
    521     NoticeDialogListener mListener;
    522     
    523     // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener
    524     &#64;Override
    525     public void onAttach(Activity activity) {
    526         super.onAttach(activity);
    527         // Verify that the host activity implements the callback interface
    528         try {
    529             // Instantiate the NoticeDialogListener so we can send events to the host
    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         }
    536     }
    537     ...
    538 }
    539 </pre>
    540 
    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
    543 events through an implementation of the {@code NoticeDialogListener} interface:</p>
    544 
    545 <pre>
    546 public class MainActivity extends FragmentActivity
    547                           implements NoticeDialogFragment.NoticeDialogListener{
    548     ...
    549     
    550     public void showNoticeDialog() {
    551         // Create an instance of the dialog fragment and show it
    552         DialogFragment dialog = new NoticeDialogFragment();
    553         dialog.show(getSupportFragmentManager(), "NoticeDialogFragment");
    554     }
    555 
    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
    559     &#64;Override
    560     public void onDialogPositiveClick(DialogFragment dialog) {
    561         // User touched the dialog's positive button
    562         ...
    563     }
    564 
    565     &#64;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}&mdash;which is
    574 enforced by the {@link android.support.v4.app.Fragment#onAttach onAttach()}
    575 callback method shown above&mdash;the dialog fragment can use the
    576 interface callback methods to deliver click events to the activity:</p>
    577 
    578 <pre>
    579 public class NoticeDialogFragment extends DialogFragment {
    580     ...
    581 
    582     &#64;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
    590                        mListener.onDialogPositiveClick(NoticeDialogFragment.this);
    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
    596                        mListener.onDialogNegativeClick(NoticeDialogFragment.this);
    597                    }
    598                });
    599         return builder.create();
    600     }
    601 }
    602 </pre>
    603 
    604 
    605 
    606 <h2 id="ShowingADialog">Showing a Dialog</h2>
    607 
    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>
    612 
    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>
    618 
    619 <pre>
    620 public void confirmFireMissiles() {
    621     DialogFragment newFragment = new FireMissilesDialogFragment();
    622     newFragment.show(getSupportFragmentManager(), "missiles");
    623 }
    624 </pre>
    625 
    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>
    630 
    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 
    652 <pre>
    653 public class CustomDialogFragment extends DialogFragment {
    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     &#64;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     &#64;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 }
    675 </pre>
    676 
    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();
    683     CustomDialogFragment newFragment = new CustomDialogFragment();
    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 &lt;!-- Default boolean values -->
    715 &lt;resources>
    716     &lt;bool name="large_layout">false&lt;/bool>
    717 &lt;/resources>
    718 </pre>
    719 
    720 <p class="code-caption">res/values-large/bools.xml</p>
    721 <pre>
    722 &lt;!-- Large screen boolean values -->
    723 &lt;resources>
    724     &lt;bool name="large_layout">true&lt;/bool>
    725 &lt;/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 &#64;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 &lt;activity&gt;}</a> manifest element:</p>
    758 
    759 <pre>
    760 &lt;activity android:theme="&#64;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 
    767 
    768 <h2 id="DismissingADialog">Dismissing a Dialog</h2>
    769 
    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>
    772 
    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>
    777 
    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>
    782 
    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>
    788 
    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>
    792 
    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>
    802 
    803 
    804