804 lines
34 KiB
Plaintext
804 lines
34 KiB
Plaintext
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 &
|
|
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—including
|
|
custom layouts and those described in the <a
|
|
href="{@docRoot}design/building-blocks/dialogs.html">Dialogs</a>
|
|
design guide—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 {
|
|
@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">
|
|
@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">
|
|
@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() {
|
|
@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() {
|
|
@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() {
|
|
@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>
|
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
android:orientation="vertical"
|
|
android:layout_width="wrap_content"
|
|
android:layout_height="wrap_content">
|
|
<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" />
|
|
<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" />
|
|
<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"/>
|
|
</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>
|
|
@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() {
|
|
@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
|
|
<activity>}</a> manifest element:</p>
|
|
|
|
<pre>
|
|
<activity android:theme="@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
|
|
@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
|
|
@Override
|
|
public void onDialogPositiveClick(DialogFragment dialog) {
|
|
// User touched the dialog's positive button
|
|
...
|
|
}
|
|
|
|
@Override
|
|
public void onDialogNegativeClick(DialogFragment dialog) {
|
|
// User touched the dialog's negative button
|
|
...
|
|
}
|
|
}
|
|
</pre>
|
|
|
|
<p>Because the host activity implements the {@code NoticeDialogListener}—which is
|
|
enforced by the {@link android.support.v4.app.Fragment#onAttach onAttach()}
|
|
callback method shown above—the dialog fragment can use the
|
|
interface callback methods to deliver click events to the activity:</p>
|
|
|
|
<pre>
|
|
public class NoticeDialogFragment extends DialogFragment {
|
|
...
|
|
|
|
@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.onDialogPositiveClick(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. */
|
|
@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. */
|
|
@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>
|
|
<!-- Default boolean values -->
|
|
<resources>
|
|
<bool name="large_layout">false</bool>
|
|
</resources>
|
|
</pre>
|
|
|
|
<p class="code-caption">res/values-large/bools.xml</p>
|
|
<pre>
|
|
<!-- Large screen boolean values -->
|
|
<resources>
|
|
<bool name="large_layout">true</bool>
|
|
</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;
|
|
|
|
@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
|
|
<activity>}</a> manifest element:</p>
|
|
|
|
<pre>
|
|
<activity android:theme="@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>
|
|
|
|
|