Dialog是对话框的基类,在使用中应该避免直接实例化Dialog,可以用其子类AlertDialog。
官方规定使用 DialogFragment作为Dialog的容器,好处在于,当屏幕旋转或者用户点击返回键时,它可以帮助你管理生命周期,并且它可以根据屏幕尺寸大小和你的需要帮助你创建一个Dialog或者是一个全屏的Fragment。、
1.创建一个最简单的 AlertDialog
标准的AlertDialog包含3个部分:
1.标题Title
2.内容Content area
3.动作按钮Action buttons(Positive,Negative,Neutral)
public class AlertDialogFragment extends DialogFragment
implements DialogInterface.OnClickListener
{
public static AlertDialogFragment newInstance(String message)
{
AlertDialogFragment adf = new AlertDialogFragment();
Bundle bundle = new Bundle();
bundle.putString("alert-message", message);
adf.setArguments(bundle);
return adf;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setCancelable(true);
int style = DialogFragment.STYLE_NORMAL, theme = 0;
setStyle(style,theme);
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
AlertDialog.Builder b =
new AlertDialog.Builder(getActivity())
.setTitle("Alert!!")
.setPositiveButton("Ok", this)
.setNegativeButton("Cancel", this)
.setMessage(this.getArguments().getString("alert-message"));
return b.create();
}
public void onClick(DialogInterface dialog, int which)
{
}
}
显示对话框:
FragmentTransaction ft =
getFragmentManager().beginTransaction();
AlertDialogFragment adf =
AlertDialogFragment.newInstance(
"Alert Message");
adf.show(ft, "ALERT_DIALOG_TAG");
2.创建列表Dialog
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
AlertDialog.Builder b =
new AlertDialog.Builder(getActivity())
.setTitle("Alert!!")
.setPositiveButton("Ok", this)
.setNegativeButton("Cancel", this)
.setItems(new String[] {"a", "b", "c"}, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getActivity(), "点击了第"+ (which+1) +"项", Toast.LENGTH_SHORT).show();
}
});
return b.create();
}
如果需要将动态数据作为列表项,可以使用setAdapter (ListAdapter adapter, DialogInterface.OnClickListener listener)
3.创建单选/多选Dialog单选:
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
AlertDialog.Builder b =
new AlertDialog.Builder(getActivity())
.setTitle("Alert!!")
.setPositiveButton("Ok", this)
.setNegativeButton("Cancel", this)
.setSingleChoiceItems(new String[] {"a", "b", "c"}, -1, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
return b.create();
}
多选:
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
AlertDialog.Builder b =
new AlertDialog.Builder(getActivity())
.setTitle("Alert!!")
.setPositiveButton("Ok", this)
.setNegativeButton("Cancel", this)
.setMultiChoiceItems(new String[] {"a", "b", "c"}, null, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which,
boolean isChecked) {
}
});
return b.create();
}
4.自定义布局的Dialog
需要在onCreateView中加载自定义布局,再调用show显示。
public class HelpDialogFragment extends DialogFragment implements
View.OnClickListener {
public static HelpDialogFragment newInstance(int helpResId) {
HelpDialogFragment hdf = new HelpDialogFragment();
Bundle bundle = new Bundle();
bundle.putInt("help_resource", helpResId);
hdf.setArguments(bundle);
return hdf;
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
this.setCancelable(true);
int style = DialogFragment.STYLE_NORMAL, theme = 0;
setStyle(style, theme);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle icicle) {
View v = inflater.inflate(R.layout.help_dialog, container, false);
TextView tv = (TextView) v.findViewById(R.id.helpmessage);
tv.setText(getActivity().getResources().getText(
getArguments().getInt("help_resource")));
Button closeBtn = (Button) v.findViewById(R.id.btn_close);
closeBtn.setOnClickListener(this);
return v;
}
public void onClick(View v) {
dismiss();
}
}
布局:help_dialog:
<?xml version="1.0" encoding="utf-8"?>
<!-- /res/layout/help_dialog.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:padding="4dip"
android:layout_width="match_parent" android:layout_height="match_parent">
<TextView
android:id="@+id/helpmessage"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:text="Help Text"
android:layout_weight="1"
android:layout_gravity="center_vertical|center_horizontal"
android:textAppearance="?android:attr/textAppearanceMedium"
android:gravity="top|center_horizontal" />
<Button android:id="@+id/btn_close"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0"
android:text="Close">
</Button>
</LinearLayout>
显示:
FragmentTransaction ft =
getFragmentManager().beginTransaction();
HelpDialogFragment hdf =
HelpDialogFragment.newInstance(
R.string.help_text);
hdf.show(ft, "HELP_DIALOG_TAG");
5.对话框的关联
可以通过Fragment的回退栈设置2个前后关联的Dialog:第一个Dialog点击按钮打开第二个Dialog,第二个Dialog按返回键重新显示第一个Dialog,这种逻辑在屏幕旋转时依然有效。
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.remove(this);
//加入回退栈
ft.addToBackStack(null);
HelpDialogFragment hdf =
HelpDialogFragment.newInstance(R.string.help1);
hdf.show(ft, MainActivity.HELP_DIALOG_TAG);
以上代码写在一个DIalog的Button中,点击Button,显示上面的HelpDialogFragment,再按返回键,退出HelpDialogFragment,显示刚才的Dialog。
6.对话框回调。
如果希望在点击Dialog后通知创建它的activity或者 fragment ,一种方法是直接在OnclickListener里面写逻辑,更通用的方法是,在DialogFragment内定义一个接口,为每个按钮的点击事件设置回调方法。这样一来,所有实现接口的activity或者 fragment都能在回调方法中处理按钮逻辑。
DialogFragment:
public class AlertDialogFragment extends DialogFragment {
private NoticeDialogListener mListener;
public interface NoticeDialogListener {
public void onDialogPositiveClick(DialogFragment dialog);
public void onDialogNegativeClick(DialogFragment dialog);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setCancelable(true);
int style = DialogFragment.STYLE_NORMAL, theme = 0;
setStyle(style, theme);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof NoticeDialogListener) {
mListener = (NoticeDialogListener) activity;
}
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setPositiveButton("ok", new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
if (mListener != null) {
mListener.onDialogPositiveClick(AlertDialogFragment.this);
}
}
}).setNegativeButton("cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mListener.onDialogNegativeClick(AlertDialogFragment.this);
}
});;
return builder.create();
}
}
Activity:
public class MainActivity extends Activity implements NoticeDialogListener
{
……
private void testAlertDialog()
{
FragmentTransaction ft =
getFragmentManager().beginTransaction();
AlertDialogFragment adf = new AlertDialogFragment();
adf.show(ft, ALERT_DIALOG_TAG);
}
@Override
public void onDialogPositiveClick(DialogFragment dialog) {
Toast.makeText(this, "点击了ok按钮", Toast.LENGTH_SHORT).show();
}
@Override
public void onDialogNegativeClick(DialogFragment dialog) {
Toast.makeText(this, "点击了cancel按钮", Toast.LENGTH_SHORT).show();
}
……
}
这是使用了设计模式中的观察者模式
7.onCancel,onDismiss
以下情况会调用DialogFragment的onCancel回调方法:
Dialog显示时,按返回键,回调方法调用过程:
onCancel-》onDismiss-》onDestroy
除了以上情况,以下情况会调用DialogFragment的onDismiss回调方法:
旋转屏幕,回调方法调用过程:onDestroy-》onDismiss
注:横竖屏切换时,DialogFragment会处理Dialog的生命周期,使其仍然显示在前台。