1. Dialog
The Dialog class is the base class for dialogs, but you should avoid instantiating Dialog directly. Instead, use one of the following subclasses:
<1>AlertDialog
A dialog that can show a title, up to three buttons, a list of selectable items, or a custom layout.
<2>DatePickerDialog ot TimePickerDialog
A dialog with a pre-defined UI that allows the user to select a date or time.
Use a DialogFragment as a container for dialog:
<1> handles lifecycle event (such as when the user presses the Back button or rotates the screen)
<2> reuse the dialog`s UI as an embeddable component in a larger UI, just like a traditional Fragment
2. Creating a Dialog Fragmet
<1>extending DialogFragment
<2>creating a AlterDialog in the onCreateDialog() callback method
package mirror.android.dialogtest; import android.app.AlertDialog.Builder; import android.app.Dialog; import android.app.DialogFragment; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.os.Bundle; public class FireMissilesDialogFragment extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Use the Builder class for convenient dialog construction Builder builder = new Builder(getActivity()); builder.setMessage("Fire missles?") .setPositiveButton("Fire", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // FIRE ZE MISSILES! } }) .setNegativeButton("Cancel", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // User cancelled the dialog } });
// get the AlertDialog from create!!!!!! return builder.create(); } }
Now, when you create an instance of this class and call show() on the object, the dialog appears as show above
// the second argument"fireMissonDialogFragmentTags" is a unique tag name that the sysytem uses to save and restore that fragment state when
// necessary. the tag also allows you to get a handle to the fragment by calling findFragmentbyTag() DialogFragment dialog = new FireMissilesDialogFragment(); dialog.show(getFragmentManager ,"fireMissilesDialogFragmentTags");
3. Building an Alert Dialog
<1>Title
<2>Content area
display a message, a list, or other custom layout
<3>Action buttons
no more than three action buttons
3.1 Adding buttons
<1>Positive
<2>Negative
<3>Neutral ---> "Remind me later"
3.2 Adding a list
three kinds of lists availabe with the AlertDialog APIs:
<1> traditional single-choice list
@Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Use the Builder class for convenient dialog construction Builder builder = new Builder(getActivity()); builder.setTitle("Pick a color") .setItems(R.array.dialogList, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(getActivity(), "choose " + which , Toast.LENGTH_SHORT).show(); } }); return builder.create(); }
To specify the items for the list, call setItems(), passing an array
Alternatively, specify a list using setAdapter. this allows you to back the list with dynamic data(such as from a database) using
a ListAdapter. use a Loader so that the content loads asynchronously.
<2> persistent single-choice list (radio buttons)
setSingleChoiceItems
<3> persistent multiple-choice list (checkboxes)
LogCat:
public Dialog onCreateDialog(Bundle savedInstanceState) { final ArrayList mSelectedItems = new ArrayList(); // Use the Builder class for convenient dialog construction Builder builder = new Builder(getActivity()); builder.setTitle("Pick a color") // 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.dialogList, null, new 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)){ mSelectedItems.remove(Integer.valueOf(which)); } } }) .setPositiveButton("OK", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // User clicked OK, so save the mSelectedItems results somewhere // or return them to the component that opened the dialog Log.d("Choices",mSelectedItems.toString()); } }) .setNegativeButton("Cancel", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); return builder.create(); }
3.3 Creating a Custom Layout
//dialog_layout.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ImageView android:src="@drawable/head_logo" android:layout_width="match_parent" android:layout_height="64dp" android:scaleType="center" android:background="#FFFFBB33" android:contentDescription="TestDialog" /> <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="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:hint="password"/> </LinearLayout>
@Override public Dialog onCreateDialog(Bundle savedInstanceState) { final ArrayList mSelectedItems = new ArrayList(); // Use the Builder class for convenient dialog construction Builder builder = new 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_layout, null)) .setPositiveButton("OK", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }) .setNegativeButton("Cancel", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); return builder.create(); }
To infalte the layout in the DialogFragment, get a LayoutInfater with getLayoutInflater() and call inflate()
then call setView() to place the layout in the dialog
set an activity theme like this
android:theme="@android:style/Theme.Holo.Dialog"
The activity now displays in a dialog window instead of fullscreen.
4. Passing Events Back to the Dialog`s Host
define a interface with a method for each type pf click event. Then implement that interface in the host component that will receive the action
events from the dialog
public class FireMissilesDialogFragment extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Use the Builder class for convenient dialog construction Builder builder = new 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_layout, null)) .setPositiveButton("OK", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mListener.onDialogPositiveClick(FireMissilesDialogFragment.this); } }) .setNegativeButton("Cancel", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mListener.onDialogNegativeClick(FireMissilesDialogFragment.this); } }); return builder.create(); } /* The activity that creates an instance of this dialog fragment must * implement this interface in order to receive event callbacks. * Each method passes the DialogFragment in case the host needs to query it. */ public interface NoticeDialogListener{ public void onDialogPositiveClick(DialogFragment dialog); public void onDialogNegativeClick(DialogFragment dialog); } // Use this instance of the interface to deliver action events NoticeDialogListener mListener; // Called when a fragment is first attached to its activity // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener @Override public void onAttach(Activity activity) { super.onAttach(activity); // Verify that the host activity implements the callback interface try { mListener = (NoticeDialogListener)activity; //向上转型 } catch (Exception e) { // The activity doesn't implement the interface, throw exception throw new ClassCastException(activity.toString() + " must implement NoticeDialogListener"); } } }
public class DialogTest extends Activity implements NoticeDialogListener{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_dialog_test); DialogFragment dialog = new FireMissilesDialogFragment(); dialog.show(getFragmentManager(),"fire"); } // The dialog fragment receives a reference to this Activity through the // Fragment.onAttach() callback, which it uses to call the following methods // defined by the NoticeDialogFragment.NoticeDialogListener interface @Override public void onDialogPositiveClick(DialogFragment dialog) { Toast.makeText(getApplication(), "Positive Button", Toast.LENGTH_SHORT).show(); } @Override public void onDialogNegativeClick(DialogFragment dialog) { Toast.makeText(getApplication(), "Negative Button", Toast.LENGTH_SHORT).show(); } }
5. Dismissing a Dialog
When the user touches any of the action buttons created with an Alterdialog.Builder, the sysytem dismisses the dialog for you
you can manually dismiss your dialog by calling dismiss() on your DialogFragment
In case you need to perform certain actions when the dialog goes away, you can implement the onDissmiss() method in the DialogFragment