diff --git a/docs/html/guide/topics/ui/dialogs.jd b/docs/html/guide/topics/ui/dialogs.jd index d1c24dfbbe100..62c054aeede81 100644 --- a/docs/html/guide/topics/ui/dialogs.jd +++ b/docs/html/guide/topics/ui/dialogs.jd @@ -1,680 +1,806 @@ page.title=Dialogs -parent.title=User Interface -parent.link=index.html @jd:body + +
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.
+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 android.support.v4.app.DialogFragment
+class and not android.app.DialogFragment.
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}:
+ +
+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();
+ }
+}
+
+
+
+Figure 1. +A dialog with a message and two action buttons.
+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. + + + + + +
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.
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}:
+ +
+// 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();
+
+
+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:
+ +
+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();
+
+
+The 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 presses the button.
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.
+ + + +
+Figure 3. +A dialog with a title and list.
+There are three kinds of lists available with the {@link android.app.AlertDialog} APIs:
+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 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.
+ +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.
+ + + + + +
+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> ++ +
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.
+ +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.
+ +
+@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();
+}
+
+
+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:
+ ++<activity android:theme="@android:style/Theme.Holo.Dialog" > ++
That's it. The activity now displays in a dialog window instead of fullscreen.
+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:
+ +
+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 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:
+ +
+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");
+ }
+
+ @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
+ ...
+ }
+}
+
+
+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();
+ }
+}
+
+
+
+
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.
+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.
-Note: If you decide to create a dialog outside of the
-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)}.
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:
-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:
-static final int DIALOG_PAUSED_ID = 0; -static final int DIALOG_GAMEOVER_ID = 1; -- -
Then, define the {@link android.app.Activity#onCreateDialog(int)} callback with a -switch case for each ID:
-
-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;
- }
- return dialog;
+public void confirmFireMissiles() {
+ DialogFragment newFragment = FireMissilesDialog.newInstance(this);
+ newFragment.show(getSupportFragmentManager(), "missiles");
}
-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.
+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):
When it's time to show one of the dialogs, call {@link android.app.Activity#showDialog(int)} -with the ID of a dialog:
-showDialog(DIALOG_PAUSED_ID);
+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;
+ }
+}
+And here's some code that decides whether to show the fragment as a dialog +or a fullscreen UI, based on the screen size:
+ +
+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();
+ }
+}
+
+
+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:
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:
+ ++<activity android:theme="@android:style/Theme.Holo.DialogWhenLarge" > ++ +
For more information about styling your activities with themes, see the Styles and Themes guide.
+ +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.
- - -
-
-To create an AlertDialog with side-by-side buttons like the one shown in the screenshot to the right,
-use the 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() {
- public void onClick(DialogInterface dialog, int id) {
- MyActivity.this.finish();
- }
- })
- .setNegativeButton("No", new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.cancel();
- }
- });
-AlertDialog alert = builder.create();
-
-
-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 set...Button() methods, such as
-{@link android.app.AlertDialog.Builder#setPositiveButton(CharSequence,DialogInterface.OnClickListener)
-setPositiveButton()}, that accepts the name for the button 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.
- - -
-
-To create an AlertDialog with a list of selectable items like the one shown to the right,
-use the setItems() method:
-final CharSequence[] items = {"Red", "Green", "Blue"};
-
-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();
-
-
-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 list of multiple-choice items (checkboxes) or -single-choice items (radio buttons) inside the dialog, 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
-{@link android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener)
-setSingleChoiceItems()}:
-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.
- - -
-
-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.
- -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:
- --ProgressDialog dialog = ProgressDialog.show(MyActivity.this, "", - "Loading. Please wait...", true); -- -
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). -
- -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.
- - -
-
-To show the progression with an animated progress bar:
- -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);
-
-
-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.
- -
-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);
- }
- });
- }
-
- 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
- protected void onPrepareDialog(int id, Dialog dialog) {
- switch(id) {
- case PROGRESS_DIALOG:
- progressDialog.setProgress(0);
- progressThread = new ProgressThread(handler);
- progressThread.start();
- }
-
- // 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;
- }
- }
-}
-
-
-
-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:
- -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> -- -
This XML defines an {@link android.widget.ImageView} and a {@link android.widget.TextView} - inside a {@link android.widget.LinearLayout}.
-
-Context mContext = getApplicationContext();
-Dialog dialog = new Dialog(mContext);
-
-dialog.setContentView(R.layout.custom_dialog);
-dialog.setTitle("Custom Dialog");
-
-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);
-
-
- 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.
-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:
- -
-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();
-
-
-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, 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 81aaec4a6ce5a..0000000000000 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 b2523fd5c8922..0000000000000 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 f2736bf4218df..0000000000000 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 3e74419f8976b..0000000000000 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 501f48026637f..0000000000000 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 90629f0f18f8f..0000000000000 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 0000000000000..ed952a1afc82e 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 0000000000000..8f272e56271b5 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 0000000000000..244473bd18b66 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 0000000000000..437fc74887b8c 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 0000000000000..d45b0b56922c7 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 0000000000000..2bfc1a4f40097 Binary files /dev/null and b/docs/html/images/ui/dialogs_regions.png differ