blob: d934c4b55e40c3d99169cb0e27dfa6ad140d73bc [file] [log] [blame]
page.title=Dialogs
page.tags="alertdialog","dialogfragment"
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
<li><a href="#DialogFragment">Creating a Dialog Fragment</a></li>
<li><a href="#AlertDialog">Building an Alert Dialog</a>
<ol>
<li><a href="#AddingButtons">Adding buttons</a></li>
<li><a href="#AddingAList">Adding a list</a></li>
<li><a href="#CustomLayout">Creating a Custom Layout</a></li>
</ol>
</li>
<li><a href="#PassingEvents">Passing Events Back to the Dialog's Host</a></li>
<li><a href="#ShowingADialog">Showing a Dialog</a></li>
<li><a href="#FullscreenDialog">Showing a Dialog Fullscreen or as an Embedded Fragment</a>
<ol>
<li><a href="#ActivityAsDialog">Showing an activity as a dialog on large screens</a></li>
</ol>
</li>
<li><a href="#DismissingADialog">Dismissing a Dialog</a></li>
</ol>
<h2>Key classes</h2>
<ol>
<li>{@link android.app.DialogFragment}</li>
<li>{@link android.app.AlertDialog}</li>
</ol>
<h2>See also</h2>
<ol>
<li><a href="{@docRoot}design/building-blocks/dialogs.html">Dialogs design guide</a></li>
<li><a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a> (Date/Time dialogs)</li>
</ol>
</div>
</div>
<p>A dialog is a small window that prompts the user to
make a decision or enter additional information. A dialog does not fill the screen and is
normally used for modal events that require users to take an action before they can proceed.</p>
<div class="note design">
<p><strong>Dialog Design</strong></p>
<p>For information about how to design your dialogs, including recommendations
for language, read the <a
href="{@docRoot}design/building-blocks/dialogs.html">Dialogs</a> design guide.</p>
</div>
<img src="{@docRoot}images/ui/dialogs.png" />
<p>The {@link android.app.Dialog} class is the base class for dialogs, but you
should avoid instantiating {@link android.app.Dialog} directly.
Instead, use one of the following subclasses:</p>
<dl>
<dt>{@link android.app.AlertDialog}</dt>
<dd>A dialog that can show a title, up to three buttons, a list of
selectable items, or a custom layout.</dd>
<dt>{@link android.app.DatePickerDialog} or {@link android.app.TimePickerDialog}</dt>
<dd>A dialog with a pre-defined UI that allows the user to select a date or time.</dd>
</dl>
<div class="sidebox">
<h2>Avoid ProgressDialog</h2>
<p>Android includes another dialog class called
{@link android.app.ProgressDialog} that shows a dialog with a progress bar. However, if you
need to indicate loading or indeterminate progress, you should instead follow the design
guidelines for <a href="{@docRoot}design/building-blocks/progress.html">Progress &amp;
Activity</a> and use a {@link android.widget.ProgressBar} in your layout.</p>
</div>
<p>These classes define the style and structure for your dialog, but you should
use a {@link android.support.v4.app.DialogFragment} as a container for your dialog.
The {@link android.support.v4.app.DialogFragment} class provides all the controls you
need to create your dialog and manage its appearance, instead of calling methods
on the {@link android.app.Dialog} object.</p>
<p>Using {@link android.support.v4.app.DialogFragment} to manage the dialog
ensures that it correctly handles lifecycle events
such as when the user presses the <em>Back</em> button or rotates the screen. The {@link
android.support.v4.app.DialogFragment} class also allows you to reuse the dialog's UI as an
embeddable component in a larger UI, just like a traditional {@link
android.support.v4.app.Fragment} (such as when you want the dialog UI to appear differently
on large and small screens).</p>
<p>The following sections in this guide describe how to use a {@link
android.support.v4.app.DialogFragment} in combination with an {@link android.app.AlertDialog}
object. If you'd like to create a date or time picker, you should instead read the
<a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a> guide.</p>
<p class="note"><strong>Note:</strong>
Because the {@link android.app.DialogFragment} class was originally added with
Android 3.0 (API level 11), this document describes how to use the {@link
android.support.v4.app.DialogFragment} class that's provided with the <a
href="{@docRoot}tools/support-library/index.html">Support Library</a>. By adding this library
to your app, you can use {@link android.support.v4.app.DialogFragment} and a variety of other
APIs on devices running Android 1.6 or higher. If the minimum version your app supports
is API level 11 or higher, then you can use the framework version of {@link
android.app.DialogFragment}, but be aware that the links in this document are for the support
library APIs. When using the support library,
be sure that you import <code>android.support.v4.app.DialogFragment</code>
class and <em>not</em> <code>android.app.DialogFragment</code>.</p>
<h2 id="DialogFragment">Creating a Dialog Fragment</h2>
<p>You can accomplish a wide variety of dialog designs&mdash;including
custom layouts and those described in the <a
href="{@docRoot}design/building-blocks/dialogs.html">Dialogs</a>
design guide&mdash;by extending
{@link android.support.v4.app.DialogFragment} and creating a {@link android.app.AlertDialog}
in the {@link android.support.v4.app.DialogFragment#onCreateDialog
onCreateDialog()} callback method.</p>
<p>For example, here's a basic {@link android.app.AlertDialog} that's managed within
a {@link android.support.v4.app.DialogFragment}:</p>
<pre>
public class FireMissilesDialogFragment extends DialogFragment {
&#64;Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.dialog_fire_missiles)
.setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// FIRE ZE MISSILES!
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
// Create the AlertDialog object and return it
return builder.create();
}
}
</pre>
<div class="figure" style="width:290px;margin:0 0 0 20px">
<img src="{@docRoot}images/ui/dialog_buttons.png" alt="" />
<p class="img-caption"><strong>Figure 1.</strong>
A dialog with a message and two action buttons.</p>
</div>
<p>Now, when you create an instance of this class and call {@link
android.support.v4.app.DialogFragment#show show()} on that object, the dialog appears as
shown in figure 1.</p>
<p>The next section describes more about using the {@link android.app.AlertDialog.Builder}
APIs to create the dialog.</p>
<p>Depending on how complex your dialog is, you can implement a variety of other callback
methods in the {@link android.support.v4.app.DialogFragment}, including all the basic
<a href="{@docRoot}guide/components/fragments.html#Lifecycle">fragment lifecycle methods</a>.
<h2 id="AlertDialog">Building an Alert Dialog</h2>
<p>The {@link android.app.AlertDialog} class allows you to build a variety of dialog designs and
is often the only dialog class you'll need.
As shown in figure 2, there are three regions of an alert dialog:</p>
<div class="figure" style="width:311px;margin-top:0">
<img src="{@docRoot}images/ui/dialogs_regions.png" alt="" style="margin-bottom:0"/>
<p class="img-caption"><strong>Figure 2.</strong> The layout of a dialog.</p>
</div>
<ol>
<li><b>Title</b>
<p>This is optional and should be used only when the content area
is occupied by a detailed message, a list, or custom layout. If you need to state
a simple message or question (such as the dialog in figure 1), you don't need a title.</li>
<li><b>Content area</b>
<p>This can display a message, a list, or other custom layout.</p></li>
<li><b>Action buttons</b>
<p>There should be no more than three action buttons in a dialog.</p></li>
</ol>
<p>The {@link android.app.AlertDialog.Builder}
class provides APIs that allow you to create an {@link android.app.AlertDialog}
with these kinds of content, including a custom layout.</p>
<p>To build an {@link android.app.AlertDialog}:</p>
<pre>
<b>// 1. Instantiate an {@link android.app.AlertDialog.Builder} with its constructor</b>
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
<b>// 2. Chain together various setter methods to set the dialog characteristics</b>
builder.setMessage(R.string.dialog_message)
.setTitle(R.string.dialog_title);
<b>// 3. Get the {@link android.app.AlertDialog} from {@link android.app.AlertDialog.Builder#create()}</b>
AlertDialog dialog = builder.create();
</pre>
<p>The following topics show how to define various dialog attributes using the
{@link android.app.AlertDialog.Builder} class.</p>
<h3 id="AddingButtons">Adding buttons</h3>
<p>To add action buttons like those in figure 2,
call the {@link android.app.AlertDialog.Builder#setPositiveButton setPositiveButton()} and
{@link android.app.AlertDialog.Builder#setNegativeButton setNegativeButton()} methods:</p>
<pre style="clear:right">
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Add the buttons
builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User clicked OK button
}
});
builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
// Set other dialog properties
...
// Create the AlertDialog
AlertDialog dialog = builder.create();
</pre>
<p>The <code>set...Button()</code> methods require a title for the button (supplied
by a <a href="{@docRoot}guide/topics/resources/string-resource.html">string resource</a>) and a
{@link android.content.DialogInterface.OnClickListener} that defines the action to take
when the user presses the button.</p>
<p>There are three different action buttons you can add:</p>
<dl>
<dt>Positive</dt>
<dd>You should use this to accept and continue with the action (the "OK" action).</dd>
<dt>Negative</dt>
<dd>You should use this to cancel the action.</dd>
<dt>Neutral</dt>
<dd>You should use this when the user may not want to proceed with the action,
but doesn't necessarily want to cancel. It appears between the positive and negative
buttons. For example, the action might be "Remind me later."</dd>
</dl>
<p>You can add only one of each button type to an {@link
android.app.AlertDialog}. That is, you cannot have more than one "positive" button.</p>
<div class="figure" style="width:290px;margin:0 0 0 40px">
<img src="{@docRoot}images/ui/dialog_list.png" alt="" />
<p class="img-caption"><strong>Figure 3.</strong>
A dialog with a title and list.</p>
</div>
<h3 id="AddingAList">Adding a list</h3>
<p>There are three kinds of lists available with the {@link android.app.AlertDialog} APIs:</p>
<ul>
<li>A traditional single-choice list</li>
<li>A persistent single-choice list (radio buttons)</li>
<li>A persistent multiple-choice list (checkboxes)</li>
</ul>
<p>To create a single-choice list like the one in figure 3,
use the {@link android.app.AlertDialog.Builder#setItems setItems()} method:</p>
<pre style="clear:right">
&#64;Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.pick_color);
.setItems(R.array.colors_array, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// The 'which' argument contains the index position
// of the selected item
}
});
return builder.create();
}
</pre>
<p>Because the list appears in the dialog's content area,
the dialog cannot show both a message and a list and you should set a title for the
dialog with {@link android.app.AlertDialog.Builder#setTitle setTitle()}.
To specify the items for the list, call {@link
android.app.AlertDialog.Builder#setItems setItems()}, passing an array.
Alternatively, you can specify a list using {@link
android.app.AlertDialog.Builder#setAdapter setAdapter()}. This allows you to back the list
with dynamic data (such as from a database) using a {@link android.widget.ListAdapter}.</p>
<p>If you choose to back your list with a {@link android.widget.ListAdapter},
always use a {@link android.support.v4.content.Loader} so that the content loads
asynchronously. This is described further in
<a href="{@docRoot}guide/topics/ui/declaring-layout.html#AdapterViews">Building Layouts
with an Adapter</a> and the <a href="{@docRoot}guide/components/loaders.html">Loaders</a>
guide.</p>
<p class="note"><strong>Note:</strong> By default, touching a list item dismisses the dialog,
unless you're using one of the following persistent choice lists.</p>
<div class="figure" style="width:290px;margin:-30px 0 0 40px">
<img src="{@docRoot}images/ui/dialog_checkboxes.png" />
<p class="img-caption"><strong>Figure 4.</strong>
A list of multiple-choice items.</p>
</div>
<h4 id="Checkboxes">Adding a persistent multiple-choice or single-choice list</h4>
<p>To add a list of multiple-choice items (checkboxes) or
single-choice items (radio buttons), use the
{@link android.app.AlertDialog.Builder#setMultiChoiceItems(Cursor,String,String,
DialogInterface.OnMultiChoiceClickListener) setMultiChoiceItems()} or
{@link android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener)
setSingleChoiceItems()} methods, respectively.</p>
<p>For example, here's how you can create a multiple-choice list like the
one shown in figure 4 that saves the selected
items in an {@link java.util.ArrayList}:</p>
<pre style="clear:right">
&#64;Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
mSelectedItems = new ArrayList(); // Where we track the selected items
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Set the dialog title
builder.setTitle(R.string.pick_toppings)
// Specify the list array, the items to be selected by default (null for none),
// and the listener through which to receive callbacks when items are selected
.setMultiChoiceItems(R.array.toppings, null,
new DialogInterface.OnMultiChoiceClickListener() {
&#64;Override
public void onClick(DialogInterface dialog, int which,
boolean isChecked) {
if (isChecked) {
// If the user checked the item, add it to the selected items
mSelectedItems.add(which);
} else if (mSelectedItems.contains(which)) {
// Else, if the item is already in the array, remove it
mSelectedItems.remove(Integer.valueOf(which));
}
}
})
// Set the action buttons
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
&#64;Override
public void onClick(DialogInterface dialog, int id) {
// User clicked OK, so save the mSelectedItems results somewhere
// or return them to the component that opened the dialog
...
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
&#64;Override
public void onClick(DialogInterface dialog, int id) {
...
}
});
return builder.create();
}
</pre>
<p>Although both a traditional list and a list with radio buttons
provide a "single choice" action, you should use {@link
android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener)
setSingleChoiceItems()} if you want to persist the user's choice.
That is, if opening the dialog again later should indicate what the user's current choice is,
then you create a list with radio buttons.</p>
<h3 id="CustomLayout">Creating a Custom Layout</h3>
<div class="figure" style="width:290px;margin:-30px 0 0 40px">
<img src="{@docRoot}images/ui/dialog_custom.png" alt="" />
<p class="img-caption"><strong>Figure 5.</strong> A custom dialog layout.</p>
</div>
<p>If you want a custom layout in a dialog, create a layout and add it to an
{@link android.app.AlertDialog} by calling {@link
android.app.AlertDialog.Builder#setView setView()} on your {@link
android.app.AlertDialog.Builder} object.</p>
<p>By default, the custom layout fills the dialog window, but you can still
use {@link android.app.AlertDialog.Builder} methods to add buttons and a title.</p>
<p>For example, here's the layout file for the dialog in Figure 5:</p>
<p style="clear:right" class="code-caption">res/layout/dialog_signin.xml</p>
<pre>
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
&lt;ImageView
android:src="@drawable/header_logo"
android:layout_width="match_parent"
android:layout_height="64dp"
android:scaleType="center"
android:background="#FFFFBB33"
android:contentDescription="@string/app_name" />
&lt;EditText
android:id="@+id/username"
android:inputType="textEmailAddress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginBottom="4dp"
android:hint="@string/username" />
&lt;EditText
android:id="@+id/password"
android:inputType="textPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginBottom="16dp"
android:fontFamily="sans-serif"
android:hint="@string/password"/>
&lt;/LinearLayout>
</pre>
<p class="note"><strong>Tip:</strong> By default, when you set an {@link android.widget.EditText}
element to use the {@code "textPassword"} input type, the font family is set to monospace, so
you should change its font family to {@code "sans-serif"} so that both text fields use
a matching font style.</p>
<p>To inflate the layout in your {@link android.support.v4.app.DialogFragment},
get a {@link android.view.LayoutInflater} with
{@link android.app.Activity#getLayoutInflater()} and call
{@link android.view.LayoutInflater#inflate inflate()}, where the first parameter
is the layout resource ID and the second parameter is a parent view for the layout.
You can then call {@link android.app.AlertDialog#setView setView()}
to place the layout in the dialog.</p>
<pre>
&#64;Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
builder.setView(inflater.inflate(R.layout.dialog_signin, null))
// Add action buttons
.setPositiveButton(R.string.signin, new DialogInterface.OnClickListener() {
&#64;Override
public void onClick(DialogInterface dialog, int id) {
// sign in the user ...
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
LoginDialogFragment.this.getDialog().cancel();
}
});
return builder.create();
}
</pre>
<div class="note">
<p><strong>Tip:</strong> If you want a custom dialog,
you can instead display an {@link android.app.Activity} as a dialog
instead of using the {@link android.app.Dialog} APIs. Simply create an activity and set its theme to
{@link android.R.style#Theme_Holo_Dialog Theme.Holo.Dialog}
in the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
&lt;activity&gt;}</a> manifest element:</p>
<pre>
&lt;activity android:theme="&#64;android:style/Theme.Holo.Dialog" >
</pre>
<p>That's it. The activity now displays in a dialog window instead of fullscreen.</p>
</div>
<h2 id="PassingEvents">Passing Events Back to the Dialog's Host</h2>
<p>When the user touches one of the dialog's action buttons or selects an item from its list,
your {@link android.support.v4.app.DialogFragment} might perform the necessary
action itself, but often you'll want to deliver the event to the activity or fragment that
opened the dialog. To do this, define an interface with a method for each type of click event.
Then implement that interface in the host component that will
receive the action events from the dialog.</p>
<p>For example, here's a {@link android.support.v4.app.DialogFragment} that defines an
interface through which it delivers the events back to the host activity:</p>
<pre>
public class NoticeDialogFragment extends DialogFragment {
/* The activity that creates an instance of this dialog fragment must
* implement this interface in order to receive event callbacks.
* Each method passes the DialogFragment in case the host needs to query it. */
public interface NoticeDialogListener {
public void onDialogPositiveClick(DialogFragment dialog);
public void onDialogNegativeClick(DialogFragment dialog);
}
// Use this instance of the interface to deliver action events
NoticeDialogListener mListener;
// Override the Fragment.onAttach() method to instantiate the NoticeDialogListener
&#64;Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Verify that the host activity implements the callback interface
try {
// Instantiate the NoticeDialogListener so we can send events to the host
mListener = (NoticeDialogListener) activity;
} catch (ClassCastException e) {
// The activity doesn't implement the interface, throw exception
throw new ClassCastException(activity.toString()
+ " must implement NoticeDialogListener");
}
}
...
}
</pre>
<p>The activity hosting the dialog creates an instance of the dialog
with the dialog fragment's constructor and receives the dialog's
events through an implementation of the {@code NoticeDialogListener} interface:</p>
<pre>
public class MainActivity extends FragmentActivity
implements NoticeDialogFragment.NoticeDialogListener{
...
public void showNoticeDialog() {
// Create an instance of the dialog fragment and show it
DialogFragment dialog = new NoticeDialogFragment();
dialog.show(getSupportFragmentManager(), "NoticeDialogFragment");
}
// The dialog fragment receives a reference to this Activity through the
// Fragment.onAttach() callback, which it uses to call the following methods
// defined by the NoticeDialogFragment.NoticeDialogListener interface
&#64;Override
public void onDialogPositiveClick(DialogFragment dialog) {
// User touched the dialog's positive button
...
}
&#64;Override
public void onDialogNegativeClick(DialogFragment dialog) {
// User touched the dialog's negative button
...
}
}
</pre>
<p>Because the host activity implements the {@code NoticeDialogListener}&mdash;which is
enforced by the {@link android.support.v4.app.Fragment#onAttach onAttach()}
callback method shown above&mdash;the dialog fragment can use the
interface callback methods to deliver click events to the activity:</p>
<pre>
public class NoticeDialogFragment extends DialogFragment {
...
&#64;Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Build the dialog and set up the button click handlers
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.dialog_fire_missiles)
.setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Send the positive button event back to the host activity
mListener.onDialogPositiveClick(NoticeDialogFragment.this);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Send the negative button event back to the host activity
mListener.onDialogNegativeClick(NoticeDialogFragment.this);
}
});
return builder.create();
}
}
</pre>
<h2 id="ShowingADialog">Showing a Dialog</h2>
<p>When you want to show your dialog, create an instance of your {@link
android.support.v4.app.DialogFragment} and call {@link android.support.v4.app.DialogFragment#show
show()}, passing the {@link android.support.v4.app.FragmentManager} and a tag name
for the dialog fragment.</p>
<p>You can get the {@link android.support.v4.app.FragmentManager} by calling
{@link android.support.v4.app.FragmentActivity#getSupportFragmentManager()} from
the {@link android.support.v4.app.FragmentActivity} or {@link
android.support.v4.app.Fragment#getFragmentManager()} from a {@link
android.support.v4.app.Fragment}. For example:</p>
<pre>
public void confirmFireMissiles() {
DialogFragment newFragment = new FireMissilesDialogFragment();
newFragment.show(getSupportFragmentManager(), "missiles");
}
</pre>
<p>The second argument, {@code "missiles"}, is a unique tag name that the system uses to save
and restore the fragment state when necessary. The tag also allows you to get a handle to
the fragment by calling {@link android.support.v4.app.FragmentManager#findFragmentByTag
findFragmentByTag()}.</p>
<h2 id="FullscreenDialog">Showing a Dialog Fullscreen or as an Embedded Fragment</h2>
<p>You might have a UI design in which you want a piece of the UI to appear as a dialog in some
situations, but as a full screen or embedded fragment in others (perhaps depending on whether
the device is a large screen or small screen). The {@link android.support.v4.app.DialogFragment}
class offers you this flexibility because it can still behave as an embeddable {@link
android.support.v4.app.Fragment}.</p>
<p>However, you cannot use {@link android.app.AlertDialog.Builder AlertDialog.Builder}
or other {@link android.app.Dialog} objects to build the dialog in this case. If
you want the {@link android.support.v4.app.DialogFragment} to be
embeddable, you must define the dialog's UI in a layout, then load the layout in the
{@link android.support.v4.app.DialogFragment#onCreateView
onCreateView()} callback.</p>
<p>Here's an example {@link android.support.v4.app.DialogFragment} that can appear as either a
dialog or an embeddable fragment (using a layout named <code>purchase_items.xml</code>):</p>
<pre>
public class CustomDialogFragment extends DialogFragment {
/** The system calls this to get the DialogFragment's layout, regardless
of whether it's being displayed as a dialog or an embedded fragment. */
&#64;Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout to use as dialog or embedded fragment
return inflater.inflate(R.layout.purchase_items, container, false);
}
/** The system calls this only when creating the layout in a dialog. */
&#64;Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// The only reason you might override this method when using onCreateView() is
// to modify any dialog characteristics. For example, the dialog includes a
// title by default, but your custom layout might not need it. So here you can
// remove the dialog title, but you must call the superclass to get the Dialog.
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
return dialog;
}
}
</pre>
<p>And here's some code that decides whether to show the fragment as a dialog
or a fullscreen UI, based on the screen size:</p>
<pre>
public void showDialog() {
FragmentManager fragmentManager = getSupportFragmentManager();
CustomDialogFragment newFragment = new CustomDialogFragment();
if (mIsLargeLayout) {
// The device is using a large layout, so show the fragment as a dialog
newFragment.show(fragmentManager, "dialog");
} else {
// The device is smaller, so show the fragment fullscreen
FragmentTransaction transaction = fragmentManager.beginTransaction();
// For a little polish, specify a transition animation
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
// To make it fullscreen, use the 'content' root view as the container
// for the fragment, which is always the root view for the activity
transaction.add(android.R.id.content, newFragment)
.addToBackStack(null).commit();
}
}
</pre>
<p>For more information about performing fragment transactions, see the
<a href="{@docRoot}guide/components/fragments.html">Fragments</a> guide.</p>
<p>In this example, the <code>mIsLargeLayout</code> boolean specifies whether the current device
should use the app's large layout design (and thus show this fragment as a dialog, rather
than fullscreen). The best way to set this kind of boolean is to declare a
<a href="{@docRoot}guide/topics/resources/more-resources.html#Bool">bool resource value</a>
with an <a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources"
>alternative resource</a> value for different screen sizes. For example, here are two
versions of the bool resource for different screen sizes:</p>
<p class="code-caption">res/values/bools.xml</p>
<pre>
&lt;!-- Default boolean values -->
&lt;resources>
&lt;bool name="large_layout">false&lt;/bool>
&lt;/resources>
</pre>
<p class="code-caption">res/values-large/bools.xml</p>
<pre>
&lt;!-- Large screen boolean values -->
&lt;resources>
&lt;bool name="large_layout">true&lt;/bool>
&lt;/resources>
</pre>
<p>Then you can initialize the {@code mIsLargeLayout} value during the activity's
{@link android.app.Activity#onCreate onCreate()} method:</p>
<pre>
boolean mIsLargeLayout;
&#64;Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mIsLargeLayout = getResources().getBoolean(R.bool.large_layout);
}
</pre>
<h3 id="ActivityAsDialog">Showing an activity as a dialog on large screens</h3>
<p>Instead of showing a dialog as a fullscreen UI when on small screens, you can accomplish
the same result by showing an {@link android.app.Activity} as a dialog when on
large screens. Which approach you choose depends on your app design, but
showing an activity as a dialog is often useful when your app is already designed for small
screens and you'd like to improve the experience on tablets by showing a short-lived activity
as a dialog.</p>
<p>To show an activity as a dialog only when on large screens,
apply the {@link android.R.style#Theme_Holo_DialogWhenLarge Theme.Holo.DialogWhenLarge}
theme to the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
&lt;activity&gt;}</a> manifest element:</p>
<pre>
&lt;activity android:theme="&#64;android:style/Theme.Holo.DialogWhenLarge" >
</pre>
<p>For more information about styling your activities with themes, see the <a
href="{@docRoot}guide/topics/ui/themes.html">Styles and Themes</a> guide.</p>
<h2 id="DismissingADialog">Dismissing a Dialog</h2>
<p>When the user touches any of the action buttons created with an
{@link android.app.AlertDialog.Builder}, the system dismisses the dialog for you.</p>
<p>The system also dismisses the dialog when the user touches an item in a dialog list, except
when the list uses radio buttons or checkboxes. Otherwise, you can manually dismiss your dialog
by calling {@link android.support.v4.app.DialogFragment#dismiss()} on your {@link
android.support.v4.app.DialogFragment}.</p>
<p>In case you need to perform certain
actions when the dialog goes away, you can implement the {@link
android.support.v4.app.DialogFragment#onDismiss onDismiss()} method in your {@link
android.support.v4.app.DialogFragment}.</p>
<p>You can also <em>cancel</em> a dialog. This is a special event that indicates the user
explicitly left the dialog without completing the task. This occurs if the user presses the
<em>Back</em> button, touches the screen outside the dialog area,
or if you explicitly call {@link android.app.Dialog#cancel()} on the {@link
android.app.Dialog} (such as in response to a "Cancel" button in the dialog).</p>
<p>As shown in the example above, you can respond to the cancel event by implementing
{@link android.support.v4.app.DialogFragment#onCancel onCancel()} in your {@link
android.support.v4.app.DialogFragment} class.</p>
<p class="note"><strong>Note:</strong> The system calls
{@link android.support.v4.app.DialogFragment#onDismiss onDismiss()} upon each event that
invokes the {@link android.support.v4.app.DialogFragment#onCancel onCancel()} callback. However,
if you call {@link android.app.Dialog#dismiss Dialog.dismiss()} or {@link
android.support.v4.app.DialogFragment#dismiss DialogFragment.dismiss()},
the system calls {@link android.support.v4.app.DialogFragment#onDismiss onDismiss()} <em>but
not</em> {@link android.support.v4.app.DialogFragment#onCancel onCancel()}. So you should generally
call {@link android.support.v4.app.DialogFragment#dismiss dismiss()} when the user presses the
<em>positive</em> button in your dialog in order to remove the dialog from view.</p>