From db705ef67bebe00deaacc12201c5d92ae8b3f851 Mon Sep 17 00:00:00 2001
From: Scott Main A dialog is usually a small window that appears in front of the current Activity.
-The underlying Activity loses focus and the dialog accepts all user interaction. Dialogs are
-normally used for notifications that should interrupt the user and to perform short tasks that
-directly relate to the application in progress (such as a progress bar or a login prompt). The {@link android.app.Dialog} class is the base class for creating dialogs. However, you
-typically should not instantiate a {@link android.app.Dialog} directly. Instead, you should use one
-of the following subclasses: If you would like to customize your own dialog, you can extend the
-base {@link android.app.Dialog} object or any of the subclasses listed above and define a new layout.
-See the section on Creating a Custom Dialog below. 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. Dialog Design For design guidelines, read Android Design's Dialogs guide. For information about how to design your dialogs, including recommendations
+ for language, read the Dialogs design guide. 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: 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 Progress &
+Activity and use a {@link android.widget.ProgressBar} in your layout. A dialog is always created and displayed as a part of an {@link android.app.Activity}.
-You should normally create dialogs from within your Activity's
-{@link android.app.Activity#onCreateDialog(int)} callback method.
-When you use this callback, the Android system automatically manages the state of
-each dialog and hooks them to the Activity, effectively making it the "owner" of each dialog.
-As such, each dialog inherits certain properties from the Activity. For example, when a dialog
-is open, the Menu key reveals the options menu defined for the Activity and the volume
-keys modify the audio stream used by the Activity. Note: If you decide to create a dialog outside of the
- When you want to show a dialog, call
-{@link android.app.Activity#showDialog(int)} and pass it an integer that uniquely identifies the
-dialog that you want to display. When a dialog is requested for the first time, Android calls
-{@link android.app.Activity#onCreateDialog(int)} from your Activity, which is
-where you should instantiate the {@link android.app.Dialog}. This callback method
-is passed the same ID that you passed to {@link android.app.Activity#showDialog(int)}.
-After you create the Dialog, return the object at the end of the method. Before the dialog is displayed, Android also calls the optional callback method
-{@link android.app.Activity#onPrepareDialog(int,Dialog)}. Define this method if you want to change
-any properties of the dialog each time it is opened. This method is called
-every time a dialog is opened, whereas {@link android.app.Activity#onCreateDialog(int)} is only
-called the very first time a dialog is opened. If you don't define
-{@link android.app.Activity#onPrepareDialog(int,Dialog) onPrepareDialog()}, then the dialog will
-remain the same as it was the previous time it was opened. This method is also passed the dialog's
-ID, along with the Dialog object you created in {@link android.app.Activity#onCreateDialog(int)
-onCreateDialog()}. The best way to define the {@link android.app.Activity#onCreateDialog(int)} and
-{@link android.app.Activity#onPrepareDialog(int,Dialog)} callback methods is with a
-switch statement that checks the id parameter that's passed into the method.
-Each case should check for a unique dialog ID and then create and define the respective Dialog.
-For example, imagine a game that uses two different dialogs: one to indicate that the game
-has paused and another to indicate that the game is over. First, define an integer ID for
-each dialog: 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. 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 Back 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). 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
+Pickers guide. Note:
+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 Support Library. 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 You can accomplish a wide variety of dialog designs—including
+custom layouts and those described in the Dialogs
+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. For example, here's a basic {@link android.app.AlertDialog} that's managed within
+a {@link android.support.v4.app.DialogFragment}: Then, define the {@link android.app.Activity#onCreateDialog(int)} callback with a
-switch case for each ID: Note: In this example, there's no code inside
-the case statements because the procedure for defining your Dialog is outside the scope
-of this section. See the section below about Creating an AlertDialog,
-offers code suitable for this example. Figure 1.
+A dialog with a message and two action buttons. When it's time to show one of the dialogs, call {@link android.app.Activity#showDialog(int)}
-with the ID of a dialog: 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. The next section describes more about using the {@link android.app.AlertDialog.Builder}
+APIs to create the dialog. 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
+fragment lifecycle methods.
- When you're ready to close your dialog, you can dismiss it by calling
-{@link android.app.Dialog#dismiss()} on the Dialog object.
-If necessary, you can also call {@link android.app.Activity#dismissDialog(int)} from the
-Activity, which effectively calls {@link android.app.Dialog#dismiss()} on the
-Dialog for you. If you are using {@link android.app.Activity#onCreateDialog(int)} to manage the state
-of your dialogs (as discussed in the previous section), then every time your dialog is
-dismissed, the state of the Dialog
-object is retained by the Activity. If you decide that you will no longer need this object or
-it's important that the state is cleared, then you should call
-{@link android.app.Activity#removeDialog(int)}. This will remove any internal references
-to the object and if the dialog is showing, it will dismiss it. If you'd like your application to perform some procedures the moment that a dialog is dismissed,
-then you should attach an on-dismiss listener to your Dialog. First define the {@link android.content.DialogInterface.OnDismissListener} interface.
-This interface has just one method,
-{@link android.content.DialogInterface.OnDismissListener#onDismiss(DialogInterface)}, which
-will be called when the dialog is dismissed.
-Then simply pass your OnDismissListener implementation to
-{@link android.app.Dialog#setOnDismissListener(DialogInterface.OnDismissListener)
-setOnDismissListener()}. However, note that dialogs can also be "cancelled." This is a special case that indicates
-the dialog was explicitly cancelled by the user. This will occur if the user presses the
-"back" button to close the dialog, or if the dialog explicitly calls {@link android.app.Dialog#cancel()}
-(perhaps from a "Cancel" button in the dialog). When a dialog is cancelled,
-the OnDismissListener will still be notified, but if you'd like to be informed that the dialog
-was explicitly cancelled (and not dismissed normally), then you should register
-an {@link android.content.DialogInterface.OnCancelListener} with
-{@link android.app.Dialog#setOnCancelListener(DialogInterface.OnCancelListener)
-setOnCancelListener()}. An {@link android.app.AlertDialog} is an extension of the {@link android.app.Dialog}
-class. It is capable of constructing most dialog user interfaces and is the suggested dialog type.
-You should use it for dialogs that use any of the following features: To create an AlertDialog, use the {@link android.app.AlertDialog.Builder} subclass.
-Get a Builder with {@link android.app.AlertDialog.Builder#AlertDialog.Builder(Context)} and
-then use the class's public methods to define all of the
-AlertDialog properties. After you're done with the Builder, retrieve the
-AlertDialog object with {@link android.app.AlertDialog.Builder#create()}. The following topics show how to define various properties of the AlertDialog using the
-AlertDialog.Builder class. If you use any of the following sample code inside your
-{@link android.app.Activity#onCreateDialog(int) onCreateDialog()} callback method,
-you can return the resulting Dialog object to display the dialog. 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: Figure 2. The layout of a dialog. 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. This can display a message, a list, or other custom layout. There should be no more than three action buttons in a dialog. To create an AlertDialog with side-by-side buttons like the one shown in the screenshot to the right,
-use the 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. To build an {@link android.app.AlertDialog}: The following topics show how to define various dialog attributes using the
+{@link android.app.AlertDialog.Builder} class. 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: First, add a message for the dialog with
-{@link android.app.AlertDialog.Builder#setMessage(CharSequence)}. Then, begin
-method-chaining and set the dialog
-to be not cancelable (so the user cannot close the dialog with the back button)
-with {@link android.app.AlertDialog.Builder#setCancelable(boolean)}. For each button,
-use one of the The In this document
+
+
-
-
-
-
-
- Key classes
+
-
+ Related tutorials
+ Key classes
-
See also
-
-
-
-
+
+
-Showing a Dialog
+Avoid ProgressDialog
+onCreateDialog() method, it will not be attached to an Activity. You can, however,
-attach it to an Activity with {@link android.app.Dialog#setOwnerActivity(Activity)}.
-static final int DIALOG_PAUSED_ID = 0;
-static final int DIALOG_GAMEOVER_ID = 1;
-
+android.support.v4.app.DialogFragment
+class and not android.app.DialogFragment.Creating a Dialog Fragment
+
+
-protected Dialog onCreateDialog(int id) {
- Dialog dialog;
- switch(id) {
- case DIALOG_PAUSED_ID:
- // do the work to define the pause Dialog
- break;
- case DIALOG_GAMEOVER_ID:
- // do the work to define the game over Dialog
- break;
- default:
- dialog = null;
+public class FireMissilesDialog 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();
}
- return dialog;
}
-
+
-showDialog(DIALOG_PAUSED_ID);
-
+Dismissing a Dialog
+Using dismiss listeners
-
-Creating an AlertDialog
-
-
-
-Adding buttons
+Building an Alert Dialog
+
+
+
+
+
+
-set...Button() methods:
-AlertDialog.Builder builder = new AlertDialog.Builder(this);
-builder.setMessage("Are you sure you want to exit?")
- .setCancelable(false)
- .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
+// 1. Instantiate an {@link android.app.AlertDialog.Builder} with its constructor
+AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+
+// 2. Chain together various setter methods to set the dialog characteristics
+builder.setMessage(R.string.dialog_message)
+ .setTitle(R.string.dialog_title);
+
+// 3. Get the {@link android.app.AlertDialog} from {@link android.app.AlertDialog.Builder#create()}
+AlertDialog dialog = builder.create();
+
+
+Adding buttons
+
+
+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) {
- MyActivity.this.finish();
+ // User clicked OK button
}
- })
- .setNegativeButton("No", new DialogInterface.OnClickListener() {
+ });
+builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
- dialog.cancel();
+ // User cancelled the dialog
}
});
-AlertDialog alert = builder.create();
+// Set other dialog properties
+...
+
+// Create the AlertDialog
+AlertDialog dialog = builder.create();
-set...Button() methods, such as
-{@link android.app.AlertDialog.Builder#setPositiveButton(CharSequence,DialogInterface.OnClickListener)
-setPositiveButton()}, that accepts the name for the button and a
+set...Button() methods require a title for the button (supplied
+by a string resource) and a
{@link android.content.DialogInterface.OnClickListener} that defines the action to take
-when the user selects the button.
Note: You can only add one of each button type to the -AlertDialog. That is, you cannot have more than one "positive" button. This limits the number -of possible buttons to three: positive, neutral, and negative. These names are technically irrelevant to the -actual functionality of your buttons, but should help you keep track of which one does what.
+There are three different action buttons you can add:
+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.
-
-To create an AlertDialog with a list of selectable items like the one shown to the right,
-use the setItems() method:
+Figure 3. +A dialog with a title and list.
+
-final CharSequence[] items = {"Red", "Green", "Blue"};
+Adding a list
-AlertDialog.Builder builder = new AlertDialog.Builder(this);
-builder.setTitle("Pick a color");
-builder.setItems(items, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int item) {
- Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
- }
-});
-AlertDialog alert = builder.create();
-
+There are three kinds of lists available with the {@link android.app.AlertDialog} APIs:
+First, add a title to the dialog with -{@link android.app.AlertDialog.Builder#setTitle(CharSequence)}. -Then, add a list of selectable items with -{@link android.app.AlertDialog.Builder#setItems(CharSequence[],DialogInterface.OnClickListener) -setItems()}, which accepts the array of items to display and a -{@link android.content.DialogInterface.OnClickListener} that defines the action to take -when the user selects an item.
+To create a single-choice list like the one in figure 3, +use the {@link android.app.AlertDialog.Builder#setItems setItems()} method:
+ +
+@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();
+}
+
+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}.
+ +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 +Building Layouts +with an Adapter and the Loaders +guide.
+ +Note: By default, touching a list item dismisses the dialog, +unless you're using one of the following persistent choice lists.
+ +
+Figure 4. +A list of multiple-choice items.
+
+To create a list of multiple-choice items (checkboxes) or -single-choice items (radio buttons) inside the dialog, use the +
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()} and -{@link android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) -setSingleChoiceItems()} methods, respectively. -If you create one of these selectable lists in the -{@link android.app.Activity#onCreateDialog(int) onCreateDialog()} callback method, -Android manages the state of the list for you. As long as the Activity is active, -the dialog remembers the items that were previously selected, but when the user exits the -Activity, the selection is lost. - -
Note: To save the selection when the user leaves or -pauses the Activity, you must properly save and restore the setting throughout -the activity lifecycle. -To permanently save the selections, even when the Activity process is completely shutdown, -you need to save the settings -with one of the Data -Storage techniques.
- -To create an AlertDialog with a list of single-choice items like the one shown to the right,
-use the same code from the previous example, but replace the setItems() method with
+DialogInterface.OnMultiChoiceClickListener) setMultiChoiceItems()} or
{@link android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener)
-setSingleChoiceItems()}:
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}:
+ +
+@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();
+}
+
+
+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.
+ + -
-final CharSequence[] items = {"Red", "Green", "Blue"};
-AlertDialog.Builder builder = new AlertDialog.Builder(this);
-builder.setTitle("Pick a color");
-builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int item) {
- Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
- }
-});
-AlertDialog alert = builder.create();
-
-The second parameter in the -{@link android.app.AlertDialog.Builder#setSingleChoiceItems(CharSequence[],int,DialogInterface.OnClickListener) -setSingleChoiceItems()} method is an integer value for the checkedItem, which indicates the -zero-based list position of the default selected item. Use "-1" to indicate that no item should be -selected by default.
+
+Figure 5. A custom dialog layout.
+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.
+ +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.
-For example, here's the layout file for the dialog in Figure 5:
-
+res/layout/dialog_signin.xml
++<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> +-
A {@link android.app.ProgressDialog} is an extension of the {@link android.app.AlertDialog} -class that can display a progress animation in the form of a spinning wheel, for a task with -progress that's undefined, or a progress bar, for a task that has a defined progression. -The dialog can also provide buttons, such as one to cancel a download.
+Tip: 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.
-Opening a progress dialog can be as simple as calling -{@link android.app.ProgressDialog#show(Context,CharSequence,CharSequence) -ProgressDialog.show()}. For example, the progress dialog shown to the right can be -easily achieved without managing the dialog through the -{@link android.app.Activity#onCreateDialog(int)} callback, -as shown here:
+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.
-ProgressDialog dialog = ProgressDialog.show(MyActivity.this, "",
- "Loading. Please wait...", true);
+@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) {
+ NoticeDialog.this.getDialog().cancel();
+ }
+ });
+ return builder.create();
+}
-The first parameter is the application {@link android.content.Context}, -the second is a title for the dialog (left empty), the third is the message, -and the last parameter is whether the progress -is indeterminate (this is only relevant when creating a progress bar, which is -discussed in the next section). -
+Tip: 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 {@code +<activity>} manifest element:
-The default style of a progress dialog is the spinning wheel. -If you want to create a progress bar that shows the loading progress with granularity, -some more code is required, as discussed in the next section.
++<activity android:theme="@android:style/Theme.Holo.Dialog" > ++
That's it. The activity now displays in a dialog window instead of fullscreen.
+
+To show the progression with an animated progress bar:
+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.
-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:
-For example, your setup might look like this:
-ProgressDialog progressDialog;
-progressDialog = new ProgressDialog(mContext);
-progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
-progressDialog.setMessage("Loading...");
-progressDialog.setCancelable(false);
+public class NoticeDialog 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
+ static NoticeDialogListener mListener;
+
+ /* Call this to instantiate a new NoticeDialog.
+ * @param activity The activity hosting the dialog, which must implement the
+ * NoticeDialogListener to receive event callbacks.
+ * @returns A new instance of NoticeDialog.
+ * @throws ClassCastException if the host activity does not
+ * implement NoticeDialogListener
+ */
+ public static NoticeDialog newInstance(Activity activity) {
+ // Verify that the host activity implements the callback interface
+ try {
+ // Instantiate the NoticeDialogListener so we can send events with it
+ mListener = (NoticeDialogListener) activity;
+ } catch (ClassCastException e) {
+ // The activity doesn't implement the interface, throw exception
+ throw new ClassCastException(activity.toString()
+ + " must implement NoticeDialogListener");
+ }
+ NoticeDialog frag = new NoticeDialog();
+ return frag;
+ }
+
+ ...
+}
-The setup is simple. Most of the code needed to create a progress dialog is actually -involved in the process that updates it. You might find that it's -necessary to create a second thread in your application for this work and then report the progress -back to the Activity's UI thread with a {@link android.os.Handler} object. -If you're not familiar with using additional -threads with a Handler, see the example Activity below that uses a second thread to -increment a progress dialog managed by the Activity.
- - - - -
- Example ProgressDialog with a second thread
- This example uses a second thread to track the progress of a process (which actually just -counts up to 100). The thread sends a {@link android.os.Message} back to the main -Activity through a {@link android.os.Handler} each time progress is made. The main Activity then updates the -ProgressDialog.
+The activity hosting the dialog creates and shows an instance of the dialog +by calling {@code NoticeDialog.newInstance()} and receives the dialog's +events through an implementation of the {@code NoticeDialogListener} interface:
-package com.example.progressdialog;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.app.ProgressDialog;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-
-public class NotificationTest extends Activity {
- static final int PROGRESS_DIALOG = 0;
- Button button;
- ProgressThread progressThread;
- ProgressDialog progressDialog;
-
- /** Called when the activity is first created. */
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- // Setup the button that starts the progress dialog
- button = (Button) findViewById(R.id.progressDialog);
- button.setOnClickListener(new OnClickListener(){
- public void onClick(View v) {
- showDialog(PROGRESS_DIALOG);
- }
- });
+public class MainActivity extends FragmentActivity
+ implements NoticeDialog.NoticeDialogListener{
+ ...
+
+ public void showNoticeDialog() {
+ // Create an instance of the dialog fragment and show it
+ DialogFragment dialog = NoticeDialog.newInstance(this);
+ dialog.show(getSupportFragmentManager(), "NoticeDialog");
}
-
- protected Dialog onCreateDialog(int id) {
- switch(id) {
- case PROGRESS_DIALOG:
- progressDialog = new ProgressDialog(NotificationTest.this);
- progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
- progressDialog.setMessage("Loading...");
- return progressDialog;
- default:
- return null;
- }
+
+ @Override
+ public void onDialogPositiveClick(DialogFragment dialog) {
+ // User touched the dialog's positive button
+ ...
}
@Override
- protected void onPrepareDialog(int id, Dialog dialog) {
- switch(id) {
- case PROGRESS_DIALOG:
- progressDialog.setProgress(0);
- progressThread = new ProgressThread(handler);
- progressThread.start();
+ public void onDialogNegativeClick(DialogFragment dialog) {
+ // User touched the dialog's negative button
+ ...
}
+}
+
- // Define the Handler that receives messages from the thread and update the progress
- final Handler handler = new Handler() {
- public void handleMessage(Message msg) {
- int total = msg.arg1;
- progressDialog.setProgress(total);
- if (total >= 100){
- dismissDialog(PROGRESS_DIALOG);
- progressThread.setState(ProgressThread.STATE_DONE);
- }
- }
- };
-
- /** Nested class that performs progress calculations (counting) */
- private class ProgressThread extends Thread {
- Handler mHandler;
- final static int STATE_DONE = 0;
- final static int STATE_RUNNING = 1;
- int mState;
- int total;
-
- ProgressThread(Handler h) {
- mHandler = h;
- }
-
- public void run() {
- mState = STATE_RUNNING;
- total = 0;
- while (mState == STATE_RUNNING) {
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- Log.e("ERROR", "Thread Interrupted");
- }
- Message msg = mHandler.obtainMessage();
- msg.arg1 = total;
- mHandler.sendMessage(msg);
- total++;
- }
- }
-
- /* sets the current state for the thread,
- * used to stop the thread */
- public void setState(int state) {
- mState = state;
- }
+Because the host activity implements the {@code NoticeDialogListener}—which is +enforced by the {@code newInstance()} method shown above—the dialog fragment can use the +interface callback methods to deliver click events to the activity:
+ +
+public class NoticeDialog 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(NoticeDialog.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(NoticeDialog.this);
+ }
+ });
+ return builder.create();
}
}
-
-If you want a customized design for a dialog, you can create your own layout -for the dialog window with layout and widget elements. -After you've defined your layout, pass the root View object or -layout resource ID to {@link android.app.Dialog#setContentView(View)}.
+For example, to create the dialog shown to the right:
+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.
+ +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:
-custom_dialog.xml:
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/layout_root"
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:padding="10dp"
- >
- <ImageView android:id="@+id/image"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:layout_marginRight="10dp"
- />
- <TextView android:id="@+id/text"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:textColor="#FFF"
- />
-</LinearLayout>
+public void confirmFireMissiles() {
+ DialogFragment newFragment = FireMissilesDialog.newInstance(this);
+ newFragment.show(getSupportFragmentManager(), "missiles");
+}
- This XML defines an {@link android.widget.ImageView} and a {@link android.widget.TextView} - inside a {@link android.widget.LinearLayout}.
-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()}.
+ + + + +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}.
+ +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.
+ +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 purchase_items.xml):
-Context mContext = getApplicationContext();
-Dialog dialog = new Dialog(mContext);
+public class CustomLayoutDialog 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;
+ }
+}
+
-dialog.setContentView(R.layout.custom_dialog);
-dialog.setTitle("Custom Dialog");
+And here's some code that decides whether to show the fragment as a dialog +or a fullscreen UI, based on the screen size:
-TextView text = (TextView) dialog.findViewById(R.id.text); -text.setText("Hello, this is a custom dialog!"); -ImageView image = (ImageView) dialog.findViewById(R.id.image); -image.setImageResource(R.drawable.android); +
+public void showDialog() {
+ FragmentManager fragmentManager = getSupportFragmentManager();
+ CustomLayoutDialog newFragment = new CustomLayoutDialog();
+
+ 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();
+ }
+}
- After you instantiate the Dialog, set your custom layout as the dialog's content view with - {@link android.app.Dialog#setContentView(int)}, passing it the layout resource ID. - Now that the Dialog has a defined layout, you can capture View objects from the layout with - {@link android.app.Dialog#findViewById(int)} and modify their content.
-For more information about performing fragment transactions, see the +Fragments guide.
-In this example, the mIsLargeLayout 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
+bool resource value
+with an alternative resource value for different screen sizes. For example, here are two
+versions of the bool resource for different screen sizes:
A dialog made with the base Dialog class must have a title. If you don't call -{@link android.app.Dialog#setTitle(CharSequence) setTitle()}, then the space used for the title -remains empty, but still visible. If you don't want -a title at all, then you should create your custom dialog using the -{@link android.app.AlertDialog} class. However, because an AlertDialog is created easiest with -the {@link android.app.AlertDialog.Builder} class, you do not have access to the -{@link android.app.Dialog#setContentView(int)} method used above. Instead, you must use -{@link android.app.AlertDialog.Builder#setView(View)}. This method accepts a {@link android.view.View} object, -so you need to inflate the layout's root View object from -XML.
- -To inflate the XML layout, retrieve the {@link android.view.LayoutInflater} with -{@link android.app.Activity#getLayoutInflater()} -(or {@link android.content.Context#getSystemService(String) getSystemService()}), -and then call -{@link android.view.LayoutInflater#inflate(int, ViewGroup)}, where the first parameter -is the layout resource ID and the second is the ID of the root View. At this point, you can use -the inflated layout to find View objects in the layout and define the content for the -ImageView and TextView elements. Then instantiate the AlertDialog.Builder and set the -inflated layout for the dialog with {@link android.app.AlertDialog.Builder#setView(View)}.
- -Here's an example, creating a custom layout in an AlertDialog:
+res/values/bools.xml
++<!-- Default boolean values --> +<resources> + <bool name="large_layout">false</bool> +</resources> ++ +
res/values-large/bools.xml
++<!-- Large screen boolean values --> +<resources> + <bool name="large_layout">true</bool> +</resources> ++ +
Then you can initialize the {@code mIsLargeLayout} value during the activity's +{@link android.app.Activity#onCreate onCreate()} method:
+ +
+boolean mIsLargeLayout;
+
+@Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ mIsLargeLayout = getResources().getBoolean(R.bool.large_layout);
+}
+
+
+
+
+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.
+ +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 {@code +<activity>} manifest element:
-AlertDialog.Builder builder;
-AlertDialog alertDialog;
-
-Context mContext = getApplicationContext();
-LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);
-View layout = inflater.inflate(R.layout.custom_dialog,
- (ViewGroup) findViewById(R.id.layout_root));
-
-TextView text = (TextView) layout.findViewById(R.id.text);
-text.setText("Hello, this is a custom dialog!");
-ImageView image = (ImageView) layout.findViewById(R.id.image);
-image.setImageResource(R.drawable.android);
-
-builder = new AlertDialog.Builder(mContext);
-builder.setView(layout);
-alertDialog = builder.create();
+<activity android:theme="@android:style/Theme.Holo.DialogWhenLarge" >
-Using an AlertDialog for your custom layout lets you -take advantage of built-in AlertDialog features like managed buttons, -selectable lists, a title, an icon and so on.
+For more information about styling your activities with themes, see the Styles and Themes guide.
+ -For more information, refer to the reference documentation for the -{@link android.app.Dialog} and {@link android.app.AlertDialog.Builder} -classes.
+When the user touches any of the action buttons created with an +{@link android.app.AlertDialog.Builder}, the system dismisses the dialog for you.
+ +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}.
+ +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}.
+ +You can also cancel 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 +Back 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).
+ +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.
+ +Note: 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()} but +not {@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 +positive button in your dialog in order to remove the dialog from view.
diff --git a/docs/html/images/dialog_buttons.png b/docs/html/images/dialog_buttons.png deleted file mode 100755 index 81aaec4a6ce5..000000000000 Binary files a/docs/html/images/dialog_buttons.png and /dev/null differ diff --git a/docs/html/images/dialog_custom.png b/docs/html/images/dialog_custom.png deleted file mode 100755 index b2523fd5c892..000000000000 Binary files a/docs/html/images/dialog_custom.png and /dev/null differ diff --git a/docs/html/images/dialog_list.png b/docs/html/images/dialog_list.png deleted file mode 100755 index f2736bf4218d..000000000000 Binary files a/docs/html/images/dialog_list.png and /dev/null differ diff --git a/docs/html/images/dialog_progress_bar.png b/docs/html/images/dialog_progress_bar.png deleted file mode 100755 index 3e74419f8976..000000000000 Binary files a/docs/html/images/dialog_progress_bar.png and /dev/null differ diff --git a/docs/html/images/dialog_progress_spinning.png b/docs/html/images/dialog_progress_spinning.png deleted file mode 100755 index 501f48026637..000000000000 Binary files a/docs/html/images/dialog_progress_spinning.png and /dev/null differ diff --git a/docs/html/images/dialog_singlechoicelist.png b/docs/html/images/dialog_singlechoicelist.png deleted file mode 100755 index 90629f0f18f8..000000000000 Binary files a/docs/html/images/dialog_singlechoicelist.png and /dev/null differ diff --git a/docs/html/images/ui/dialog_buttons.png b/docs/html/images/ui/dialog_buttons.png new file mode 100644 index 000000000000..ed952a1afc82 Binary files /dev/null and b/docs/html/images/ui/dialog_buttons.png differ diff --git a/docs/html/images/ui/dialog_checkboxes.png b/docs/html/images/ui/dialog_checkboxes.png new file mode 100644 index 000000000000..8f272e56271b Binary files /dev/null and b/docs/html/images/ui/dialog_checkboxes.png differ diff --git a/docs/html/images/ui/dialog_custom.png b/docs/html/images/ui/dialog_custom.png new file mode 100644 index 000000000000..244473bd18b6 Binary files /dev/null and b/docs/html/images/ui/dialog_custom.png differ diff --git a/docs/html/images/ui/dialog_list.png b/docs/html/images/ui/dialog_list.png new file mode 100644 index 000000000000..437fc74887b8 Binary files /dev/null and b/docs/html/images/ui/dialog_list.png differ diff --git a/docs/html/images/ui/dialogs.png b/docs/html/images/ui/dialogs.png new file mode 100644 index 000000000000..d45b0b56922c Binary files /dev/null and b/docs/html/images/ui/dialogs.png differ diff --git a/docs/html/images/ui/dialogs_regions.png b/docs/html/images/ui/dialogs_regions.png new file mode 100644 index 000000000000..2bfc1a4f4009 Binary files /dev/null and b/docs/html/images/ui/dialogs_regions.png differ -- cgit v1.2.3-59-g8ed1b