dialogs.jd revision d9ec8eba56ea9f1e2b920e0a8e8b575d75a1be30
1page.title=Creating Dialogs
2parent.title=User Interface
3parent.link=index.html
4@jd:body
5
6<div id="qv-wrapper">
7  <div id="qv">
8    <h2>In this document</h2>
9    <ol>
10      <li><a href="#ShowingADialog">Showing a Dialog</a></li>
11      <li><a href="#DismissingADialog">Dismissing a Dialog</a></li>
12      <li><a href="#AlertDialog">Creating an AlertDialog</a>
13        <ol>
14          <li><a href="#AddingButtons">Adding buttons</a></li>
15          <li><a href="#AddingAList">Adding a list</a></li>
16        </ol>
17      </li>
18      <li><a href="#ProgressDialog">Creating a ProgressDialog</a>
19        <ol>
20          <li><a href="#ShowingAProgressBar">Showing a progress bar</a></li>
21        </ol>
22      </li>
23      <li><a href="#CustomDialog">Creating a Custom Dialog</a></li>
24    </ol>
25    
26    <h2>Key classes</h2>
27    <ol>
28      <li>{@link android.app.Dialog}</li>
29    </ol>
30  </div>
31</div>
32
33<p>A dialog is usually a small window that appears in front of the current Activity.
34The underlying Activity loses focus and the dialog accepts all user interaction. 
35Dialogs are normally used
36for notifications and short activities that directly relate to the application in progress.</p>
37
38<p>The Android API supports the following types of {@link android.app.Dialog} objects:</p>
39<dl>
40  <dt>{@link android.app.AlertDialog}</dt>
41  <dd>A dialog that can manage zero, one, two, or three buttons, and/or a list of
42    selectable items that can include checkboxes or radio buttons. The AlertDialog 
43    is capable of constructing most dialog user interfaces and is the suggested dialog type.
44    See <a href="#AlertDialog">Creating an AlertDialog</a> below.</dd>
45  <dt>{@link android.app.ProgressDialog}</dt>
46  <dd>A dialog that displays a progress wheel or progress bar. Because it's an extension of
47    the AlertDialog, it also supports buttons.
48    See <a href="#ProgressDialog">Creating a ProgressDialog</a> below.</dd>
49  <dt>{@link android.app.DatePickerDialog}</dt>
50  <dd>A dialog that allows the user to select a date. See the 
51    <a href="{@docRoot}resources/tutorials/views/hello-datepicker.html">Hello DatePicker</a> tutorial.</dd>
52  <dt>{@link android.app.TimePickerDialog}</dt>
53  <dd>A dialog that allows the user to select a time. See the 
54    <a href="{@docRoot}resources/tutorials/views/hello-timepicker.html">Hello TimePicker</a> tutorial.</dd>
55</dl>
56
57<p>If you would like to customize your own dialog, you can extend the
58base {@link android.app.Dialog} object or any of the subclasses listed above and define a new layout.
59See the section on <a href="#CustomDialog">Creating a Custom Dialog</a> below.</p>
60
61
62<h2 id="ShowingADialog">Showing a Dialog</h2>
63
64<p>A dialog is always created and displayed as a part of an {@link android.app.Activity}. 
65You should normally create dialogs from within your Activity's
66{@link android.app.Activity#onCreateDialog(int)} callback method. 
67When you use this callback, the Android system automatically manages the state of 
68each dialog and hooks them to the Activity, effectively making it the "owner" of each dialog.
69As such, each dialog inherits certain properties from the Activity. For example, when a dialog
70is open, the Menu key reveals the options menu defined for the Activity and the volume
71keys modify the audio stream used by the Activity.</p>
72
73<p class="note"><strong>Note:</strong> If you decide to create a dialog outside of the 
74<code>onCreateDialog()</code> method, it will not be attached to an Activity. You can, however,
75attach it to an Activity with {@link android.app.Dialog#setOwnerActivity(Activity)}.</p>
76
77<p>When you want to show a dialog, call 
78{@link android.app.Activity#showDialog(int)} and pass it an integer that uniquely identifies the 
79dialog that you want to display.</p>
80
81<p>When a dialog is requested for the first time, Android calls 
82{@link android.app.Activity#onCreateDialog(int)} from your Activity, which is
83where you should instantiate the {@link android.app.Dialog}. This callback method
84is passed the same ID that you passed to {@link android.app.Activity#showDialog(int)}. 
85After you create the Dialog, return the object at the end of the method.</p>
86
87<p>Before the dialog is displayed, Android also calls the optional callback method
88{@link android.app.Activity#onPrepareDialog(int,Dialog)}. Define this method if you want to change
89any properties of the dialog each time it is opened. This method is called
90every time a dialog is opened, whereas {@link android.app.Activity#onCreateDialog(int)} is only
91called the very first time a dialog is opened. If you don't define 
92{@link android.app.Activity#onPrepareDialog(int,Dialog) onPrepareDialog()}, then the dialog will 
93remain the same as it was the previous time it was opened. This method is also passed the dialog's
94ID, along with the Dialog object you created in {@link android.app.Activity#onCreateDialog(int)
95onCreateDialog()}.</p>
96
97<p>The best way to define the {@link android.app.Activity#onCreateDialog(int)} and 
98{@link android.app.Activity#onPrepareDialog(int,Dialog)} callback methods is with a 
99<em>switch</em> statement that checks the <var>id</var> parameter that's passed into the method. 
100Each <em>case</em> should check for a unique dialog ID and then create and define the respective Dialog.
101For example, imagine a game that uses two different dialogs: one to indicate that the game
102has paused and another to indicate that the game is over. First, define an integer ID for
103each dialog:</p>
104<pre>
105static final int DIALOG_PAUSED_ID = 0;
106static final int DIALOG_GAMEOVER_ID = 1;
107</pre>
108
109<p>Then, define the {@link android.app.Activity#onCreateDialog(int)} callback with a 
110switch case for each ID:</p>
111<pre>
112protected Dialog onCreateDialog(int id) {
113    Dialog dialog;
114    switch(id) {
115    case DIALOG_PAUSED_ID:
116        // do the work to define the pause Dialog
117        break;
118    case DIALOG_GAMEOVER_ID:
119        // do the work to define the game over Dialog
120        break;
121    default:
122        dialog = null;
123    }
124    return dialog;
125}
126</pre>
127
128<p class="note"><strong>Note:</strong> In this example, there's no code inside
129the case statements because the procedure for defining your Dialog is outside the scope
130of this section. See the section below about <a href="#AlertDialog">Creating an AlertDialog</a>,
131offers code suitable for this example.</p>
132
133<p>When it's time to show one of the dialogs, call {@link android.app.Activity#showDialog(int)}
134with the ID of a dialog:</p>
135<pre>
136showDialog(DIALOG_PAUSED_ID);
137</pre>
138
139
140<h2 id="DismissingADialog">Dismissing a Dialog</h2>
141
142<p>When you're ready to close your dialog, you can dismiss it by calling
143{@link android.app.Dialog#dismiss()} on the Dialog object.
144If necessary, you can also call {@link android.app.Activity#dismissDialog(int)} from the
145Activity, which effectively calls {@link android.app.Dialog#dismiss()} on the 
146Dialog for you.</p>
147
148<p>If you are using {@link android.app.Activity#onCreateDialog(int)} to manage the state
149of your dialogs (as discussed in the previous section), then every time your dialog is
150dismissed, the state of the Dialog
151object is retained by the Activity. If you decide that you will no longer need this object or 
152it's important that the state is cleared, then you should call
153{@link android.app.Activity#removeDialog(int)}. This will remove any internal references
154to the object and if the dialog is showing, it will dismiss it.</p>
155
156<h3>Using dismiss listeners</h3>
157
158<p>If you'd like your application to perform some procedures the moment that a dialog is dismissed, 
159then you should attach an on-dismiss listener to your Dialog.</p>
160
161<p>First define the {@link android.content.DialogInterface.OnDismissListener} interface.
162This interface has just one method,
163{@link android.content.DialogInterface.OnDismissListener#onDismiss(DialogInterface)}, which
164will be called when the dialog is dismissed.
165Then simply pass your OnDismissListener implementation to 
166{@link android.app.Dialog#setOnDismissListener(DialogInterface.OnDismissListener)
167setOnDismissListener()}.</p>
168
169<p>However, note that dialogs can also be "cancelled." This is a special case that indicates
170the dialog was explicitly cancelled by the user. This will occur if the user presses the 
171"back" button to close the dialog, or if the dialog explicitly calls {@link android.app.Dialog#cancel()}
172(perhaps from a "Cancel" button in the dialog). When a dialog is cancelled,
173the OnDismissListener will still be notified, but if you'd like to be informed that the dialog
174was explicitly cancelled (and not dismissed normally), then you should register 
175an {@link android.content.DialogInterface.OnCancelListener} with
176{@link android.app.Dialog#setOnCancelListener(DialogInterface.OnCancelListener)
177setOnCancelListener()}.</p>
178
179
180<h2 id="AlertDialog">Creating an AlertDialog</h2>
181
182<p>An {@link android.app.AlertDialog} is an extension of the {@link android.app.Dialog}
183class. It is capable of constructing most dialog user interfaces and is the suggested dialog type.
184You should use it for dialogs that use any of the following features:</p>
185<ul>
186  <li>A title</li>
187  <li>A text message</li>
188  <li>One, two, or three buttons</li>
189  <li>A list of selectable items (with optional checkboxes or radio buttons)</li>
190</ul>
191
192<p>To create an AlertDialog, use the {@link android.app.AlertDialog.Builder} subclass.
193Get a Builder with {@link android.app.AlertDialog.Builder#AlertDialog.Builder(Context)} and
194then use the class's public methods to define all of the
195AlertDialog properties. After you're done with the Builder, retrieve the 
196AlertDialog object with {@link android.app.AlertDialog.Builder#create()}.</p>
197
198<p>The following topics show how to define various properties of the AlertDialog using the
199AlertDialog.Builder class. If you use any of the following sample code inside your 
200{@link android.app.Activity#onCreateDialog(int) onCreateDialog()} callback method, 
201you can return the resulting Dialog object to display the dialog.</p>
202
203
204<h3 id="AddingButtons">Adding buttons</h3>
205
206<img src="{@docRoot}images/dialog_buttons.png" alt="" style="float:right" />
207
208<p>To create an AlertDialog with side-by-side buttons like the one shown in the screenshot to the right,
209use the <code>set...Button()</code> methods:</p>
210
211<pre>
212AlertDialog.Builder builder = new AlertDialog.Builder(this);
213builder.setMessage("Are you sure you want to exit?")
214       .setCancelable(false)
215       .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
216           public void onClick(DialogInterface dialog, int id) {
217                MyActivity.this.finish();
218           }
219       })
220       .setNegativeButton("No", new DialogInterface.OnClickListener() {
221           public void onClick(DialogInterface dialog, int id) {
222                dialog.cancel();
223           }
224       });
225AlertDialog alert = builder.create();
226</pre>
227
228<p>First, add a message for the dialog with 
229{@link android.app.AlertDialog.Builder#setMessage(CharSequence)}. Then, begin
230method-chaining and set the dialog
231to be <em>not cancelable</em> (so the user cannot close the dialog with the back button)
232with {@link android.app.AlertDialog.Builder#setCancelable(boolean)}. For each button, 
233use one of the <code>set...Button()</code> methods, such as
234{@link android.app.AlertDialog.Builder#setPositiveButton(CharSequence,DialogInterface.OnClickListener)
235setPositiveButton()}, that accepts the name for the button and a 
236{@link android.content.DialogInterface.OnClickListener} that defines the action to take 
237when the user selects the button.</p>
238
239<p class="note"><strong>Note:</strong> You can only add one of each button type to the
240AlertDialog. That is, you cannot have more than one "positive" button. This limits the number
241of possible buttons to three: positive, neutral, and negative. These names are technically irrelevant to the
242actual functionality of your buttons, but should help you keep track of which one does what.</p>
243
244
245<h3 id="AddingAList">Adding a list</h3>
246
247<img src="{@docRoot}images/dialog_list.png" alt="" style="float:right" />
248
249<p>To create an AlertDialog with a list of selectable items like the one shown to the right, 
250use the <code>setItems()</code> method:</p>
251
252<pre>
253final CharSequence[] items = {"Red", "Green", "Blue"};
254
255AlertDialog.Builder builder = new AlertDialog.Builder(this);
256builder.setTitle("Pick a color");
257builder.setItems(items, new DialogInterface.OnClickListener() {
258    public void onClick(DialogInterface dialog, int item) {
259        Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
260    }
261});
262AlertDialog alert = builder.create();
263</pre>
264
265<p>First, add a title to the dialog with 
266{@link android.app.AlertDialog.Builder#setTitle(CharSequence)}. 
267Then, add a list of selectable items with
268{@link android.app.AlertDialog.Builder#setItems(CharSequence[],DialogInterface.OnClickListener)
269setItems()}, which accepts the array of items to display and a 
270{@link android.content.DialogInterface.OnClickListener} that defines the action to take 
271when the user selects an item.</p>
272
273
274<h4>Adding checkboxes and radio buttons</h4>
275
276<img src="{@docRoot}images/dialog_singlechoicelist.png" alt="" style="float:right" />
277
278<p>To create a list of multiple-choice items (checkboxes) or 
279single-choice items (radio buttons) inside the dialog, use the
280{@link android.app.AlertDialog.Builder#setMultiChoiceItems(Cursor,String,String,
281DialogInterface.OnMultiChoiceClickListener) setMultiChoiceItems()} and 
282{@link android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) 
283setSingleChoiceItems()} methods, respectively.
284If you create one of these selectable lists in the
285{@link android.app.Activity#onCreateDialog(int) onCreateDialog()} callback method,
286Android manages the state of the list for you. As long as the Activity is active, 
287the dialog remembers the items that were previously selected, but when the user exits the
288Activity, the selection is lost.
289
290<p class="note"><strong>Note:</strong> To save the selection when the user leaves or
291pauses the Activity, you must properly save and restore the setting throughout
292the <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Activity Lifecycle</a>. 
293To permanently save the selections, even when the Activity process is completely shutdown, 
294you need to save the settings
295with one of the <a href="{@docRoot}guide/topics/data/data-storage.html">Data
296Storage</a> techniques.</p>
297
298<p>To create an AlertDialog with a list of single-choice items like the one shown to the right,
299use the same code from the previous example, but replace the <code>setItems()</code> method with
300{@link android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) 
301setSingleChoiceItems()}:</p>
302
303<pre>
304final CharSequence[] items = {"Red", "Green", "Blue"};
305
306AlertDialog.Builder builder = new AlertDialog.Builder(this);
307builder.setTitle("Pick a color");
308builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
309    public void onClick(DialogInterface dialog, int item) {
310        Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
311    }
312});
313AlertDialog alert = builder.create();
314</pre>
315
316<p>The second parameter in the
317{@link android.app.AlertDialog.Builder#setSingleChoiceItems(CharSequence[],int,DialogInterface.OnClickListener)
318setSingleChoiceItems()} method is an integer value for the <var>checkedItem</var>, which indicates the 
319zero-based list position of the default selected item. Use "-1" to indicate that no item should be 
320selected by default.</p>
321
322
323<h2 id="ProgressDialog">Creating a ProgressDialog</h2>
324
325<img src="{@docRoot}images/dialog_progress_spinning.png" alt="" style="float:right" />
326
327<p>A {@link android.app.ProgressDialog} is an extension of the {@link android.app.AlertDialog}
328class that can display a progress animation in the form of a spinning wheel, for a task with
329progress that's undefined, or a progress bar, for a task that has a defined progression.
330The dialog can also provide buttons, such as one to cancel a download.</p>
331
332<p>Opening a progress dialog can be as simple as calling 
333{@link android.app.ProgressDialog#show(Context,CharSequence,CharSequence)
334ProgressDialog.show()}. For example, the progress dialog shown to the right can be 
335easily achieved without managing the dialog through the 
336{@link android.app.Activity#onCreateDialog(int)} callback,
337as shown here:</p>
338
339<pre>
340ProgressDialog dialog = ProgressDialog.show(MyActivity.this, "", 
341                        "Loading. Please wait...", true);
342</pre>
343
344<p>The first parameter is the application {@link android.content.Context}, 
345the second is a title for the dialog (left empty), the third is the message, 
346and the last parameter is whether the progress
347is indeterminate (this is only relevant when creating a progress bar, which is
348discussed in the next section).
349</p>
350
351<p>The default style of a progress dialog is the spinning wheel.
352If you want to create a progress bar that shows the loading progress with granularity,
353some more code is required, as discussed in the next section.</p>
354
355
356<h3 id="ShowingAProgressBar">Showing a progress bar</h3>
357
358<img src="/images/dialog_progress_bar.png" alt="" style="float:right" />
359
360<p>To show the progression with an animated progress bar:</p>
361
362<ol>
363  <li>Initialize the 
364    ProgressDialog with the class constructor, 
365    {@link android.app.ProgressDialog#ProgressDialog(Context)}.</li>
366  <li>Set the progress style to "STYLE_HORIZONTAL" with 
367    {@link android.app.ProgressDialog#setProgressStyle(int)} and 
368    set any other properties, such as the message.</li>
369  <li>When you're ready to show the dialog, call 
370    {@link android.app.Dialog#show()} or return the ProgressDialog from the  
371    {@link android.app.Activity#onCreateDialog(int)} callback.</li>
372  <li>You can increment the amount of progress displayed
373    in the bar by calling either {@link android.app.ProgressDialog#setProgress(int)} with a value for 
374    the total percentage completed so far or {@link android.app.ProgressDialog#incrementProgressBy(int)}
375    with an incremental value to add to the total percentage completed so far.</li>
376</ol>
377
378<p>For example, your setup might look like this:</p>
379<pre>
380ProgressDialog progressDialog;
381progressDialog = new ProgressDialog(mContext);
382progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
383progressDialog.setMessage("Loading...");
384progressDialog.setCancelable(false);
385</pre>
386
387<p>The setup is simple. Most of the code needed to create a progress dialog is actually 
388involved in the process that updates it. You might find that it's
389necessary to create a second thread in your application for this work and then report the progress
390back to the Activity's UI thread with a {@link android.os.Handler} object. 
391If you're not familiar with using additional 
392threads with a Handler, see the example Activity below that uses a second thread to
393increment a progress dialog managed by the Activity.</p>
394
395<script type="text/javascript">
396function toggleDiv(link) {
397  var toggleable = $(link).parent();
398  if (toggleable.hasClass("closed")) {
399    $(".toggleme", toggleable).slideDown("fast");
400    toggleable.removeClass("closed");
401    toggleable.addClass("open");
402    $(".toggle-img", toggleable).attr("title", "hide").attr("src", "/assets/images/triangle-opened.png");
403  } else {
404    $(".toggleme", toggleable).slideUp("fast");
405    toggleable.removeClass("open");
406    toggleable.addClass("closed");
407    $(".toggle-img", toggleable).attr("title", "show").attr("src", "/assets/images/triangle-closed.png");
408  }
409  return false;
410}
411</script>
412<style>
413.toggleme {
414  padding:0 0 1px 0;
415}
416.toggleable a {
417  text-decoration:none;
418}
419.toggleable.closed .toggleme {
420  display:none;
421}
422#jd-content .toggle-img {
423  margin:0;
424}
425</style>
426
427<div class="toggleable closed">
428  <a href="#" onclick="return toggleDiv(this)">
429        <img src="/assets/images/triangle-closed.png" class="toggle-img" />
430        <strong>Example ProgressDialog with a second thread</strong></a>
431  <div class="toggleme">
432        <p>This example uses a second thread to track the progress of a process (which actually just
433counts up to 100). The thread sends a {@link android.os.Message} back to the main
434Activity through a {@link android.os.Handler} each time progress is made. The main Activity then updates the 
435ProgressDialog.</p>
436
437<pre>
438package com.example.progressdialog;
439
440import android.app.Activity;
441import android.app.Dialog;
442import android.app.ProgressDialog;
443import android.os.Bundle;
444import android.os.Handler;
445import android.os.Message;
446import android.view.View;
447import android.view.View.OnClickListener;
448import android.widget.Button;
449
450public class NotificationTest extends Activity {
451    static final int PROGRESS_DIALOG = 0;
452    Button button;
453    ProgressThread progressThread;
454    ProgressDialog progressDialog;
455   
456    /** Called when the activity is first created. */
457    public void onCreate(Bundle savedInstanceState) {
458        super.onCreate(savedInstanceState);
459        setContentView(R.layout.main);
460
461        // Setup the button that starts the progress dialog
462        button = (Button) findViewById(R.id.progressDialog);
463        button.setOnClickListener(new OnClickListener(){
464            public void onClick(View v) {
465                showDialog(PROGRESS_DIALOG);
466            }
467        }); 
468    }
469   
470    protected Dialog onCreateDialog(int id) {
471        switch(id) {
472        case PROGRESS_DIALOG:
473            progressDialog = new ProgressDialog(NotificationTest.this);
474            progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
475            progressDialog.setMessage("Loading...");
476            return progressDialog;
477        default:
478            return null;
479        }
480    }
481
482    &#64;Override
483    protected void onPrepareDialog(int id, Dialog dialog) {
484        switch(id) {
485        case PROGRESS_DIALOG:
486            progressDialog.setProgress(0);
487            progressThread = new ProgressThread(handler);
488            progressThread.start();
489    }
490
491    // Define the Handler that receives messages from the thread and update the progress
492    final Handler handler = new Handler() {
493        public void handleMessage(Message msg) {
494            int total = msg.arg1;
495            progressDialog.setProgress(total);
496            if (total >= 100){
497                dismissDialog(PROGRESS_DIALOG);
498                progressThread.setState(ProgressThread.STATE_DONE);
499            }
500        }
501    };
502
503    /** Nested class that performs progress calculations (counting) */
504    private class ProgressThread extends Thread {
505        Handler mHandler;
506        final static int STATE_DONE = 0;
507        final static int STATE_RUNNING = 1;
508        int mState;
509        int total;
510       
511        ProgressThread(Handler h) {
512            mHandler = h;
513        }
514       
515        public void run() {
516            mState = STATE_RUNNING;   
517            total = 0;
518            while (mState == STATE_RUNNING) {
519                try {
520                    Thread.sleep(100);
521                } catch (InterruptedException e) {
522                    Log.e("ERROR", "Thread Interrupted");
523                }
524                Message msg = mHandler.obtainMessage();
525                msg.arg1 = total;
526                mHandler.sendMessage(msg);
527                total++;
528            }
529        }
530        
531        /* sets the current state for the thread,
532         * used to stop the thread */
533        public void setState(int state) {
534            mState = state;
535        }
536    }
537}
538</pre>
539  </div> <!-- end toggleme -->
540</div> <!-- end toggleable -->
541
542
543
544<h2 id="CustomDialog">Creating a Custom Dialog</h2>
545
546<img src="{@docRoot}images/dialog_custom.png" alt="" style="float:right" />
547
548<p>If you want a customized design for a dialog, you can create your own layout
549for the dialog window with layout and widget elements.
550After you've defined your layout, pass the root View object or
551layout resource ID to {@link android.app.Dialog#setContentView(View)}.</p>
552
553<p>For example, to create the dialog shown to the right:</p>
554
555<ol>
556  <li>Create an XML layout saved as <code>custom_dialog.xml</code>:
557<pre>
558&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
559              android:id="@+id/layout_root"
560              android:orientation="horizontal"
561              android:layout_width="fill_parent"
562              android:layout_height="fill_parent"
563              android:padding="10dp"
564              >
565    &lt;ImageView android:id="@+id/image"
566               android:layout_width="wrap_content"
567               android:layout_height="fill_parent"
568               android:layout_marginRight="10dp"
569               />
570    &lt;TextView android:id="@+id/text"
571              android:layout_width="wrap_content"
572              android:layout_height="fill_parent"
573              android:textColor="#FFF"
574              />
575&lt;/LinearLayout>
576</pre>
577
578    <p>This XML defines an {@link android.widget.ImageView} and a {@link android.widget.TextView}
579    inside a {@link android.widget.LinearLayout}.</p>
580  <li>Set the above layout as the dialog's content view and define the content 
581    for the ImageView and TextView elements:</p>
582<pre>
583Context mContext = getApplicationContext();
584Dialog dialog = new Dialog(mContext);
585
586dialog.setContentView(R.layout.custom_dialog);
587dialog.setTitle("Custom Dialog");
588
589TextView text = (TextView) dialog.findViewById(R.id.text);
590text.setText("Hello, this is a custom dialog!");
591ImageView image = (ImageView) dialog.findViewById(R.id.image);
592image.setImageResource(R.drawable.android);
593</pre>
594
595    <p>After you instantiate the Dialog, set your custom layout as the dialog's content view with 
596    {@link android.app.Dialog#setContentView(int)}, passing it the layout resource ID.
597    Now that the Dialog has a defined layout, you can capture View objects from the layout with
598    {@link android.app.Dialog#findViewById(int)} and modify their content.</p>
599  </li>
600
601  <li>That's it. You can now show the dialog as described in 
602    <a href="#ShowingADialog">Showing A Dialog</a>.</li>
603</ol>
604
605<p>A dialog made with the base Dialog class must have a title. If you don't call
606{@link android.app.Dialog#setTitle(CharSequence) setTitle()}, then the space used for the title
607remains empty, but still visible. If you don't want
608a title at all, then you should create your custom dialog using the
609{@link android.app.AlertDialog} class. However, because an AlertDialog is created easiest with 
610the {@link android.app.AlertDialog.Builder} class, you do not have access to the 
611{@link android.app.Dialog#setContentView(int)} method used above. Instead, you must use 
612{@link android.app.AlertDialog.Builder#setView(View)}. This method accepts a {@link android.view.View} object,
613so you need to inflate the layout's root View object from
614XML.</p>
615
616<p>To inflate the XML layout, retrieve the {@link android.view.LayoutInflater} with 
617{@link android.app.Activity#getLayoutInflater()} 
618(or {@link android.content.Context#getSystemService(String) getSystemService()}),
619and then call
620{@link android.view.LayoutInflater#inflate(int, ViewGroup)}, where the first parameter
621is the layout resource ID and the second is the ID of the root View. At this point, you can use
622the inflated layout to find View objects in the layout and define the content for the
623ImageView and TextView elements. Then instantiate the AlertDialog.Builder and set the
624inflated layout for the dialog with {@link android.app.AlertDialog.Builder#setView(View)}.</p>
625
626<p>Here's an example, creating a custom layout in an AlertDialog:</p>
627
628<pre>
629AlertDialog.Builder builder;
630AlertDialog alertDialog;
631
632Context mContext = getApplicationContext();
633LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);
634View layout = inflater.inflate(R.layout.custom_dialog,
635                               (ViewGroup) findViewById(R.id.layout_root));
636
637TextView text = (TextView) layout.findViewById(R.id.text);
638text.setText("Hello, this is a custom dialog!");
639ImageView image = (ImageView) layout.findViewById(R.id.image);
640image.setImageResource(R.drawable.android);
641
642builder = new AlertDialog.Builder(mContext);
643builder.setView(layout);
644alertDialog = builder.create();
645</pre>
646
647<p>Using an AlertDialog for your custom layout lets you
648take advantage of built-in AlertDialog features like managed buttons,
649selectable lists, a title, an icon and so on.</p>
650
651<p>For more information, refer to the reference documentation for the 
652{@link android.app.Dialog} and {@link android.app.AlertDialog.Builder} 
653classes.</p>
654
655
656
657