DialogFragment 意义
- 它和
Fragment
基本一致的生命周期,因此便于Activity
更好的控制管理DialogFragment
。 - 随屏幕旋转(横竖屏幕切换)
DialogFragment
对话框随之自动调整对话框大小。AlertDialog
和PopupWindow
随屏幕切换而消失,并且如果处理不当很可能引发异常。 DialogFragment
的出现完美的解决了横竖屏幕切换Dialog
消失的问题。
如何使用DialogFragment
有两种方法
实现onCreateDialog方法
通过继承DialogFragment
并且实现它的onCreateDialog(Bundle savedInstanceState)
方法来创建一个DialogFragment
,这个方法返回的是一个Dialog
,意味着我们需要创建一个AlertDialog
,并返回。
public class LoginDialogFragment extends DialogFragment
{
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.fragment_login_dialog, null);
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
builder.setView(view)
// Add action buttons
.setPositiveButton("Sign in",
new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int id)
{
}
}).setNegativeButton("Cancel", null);
return builder.create();
}
}
实现onCreateView方法
通过继承DialogFragment
并且实现它的onCreateView(LayoutInflater, ViewGroup, Bundle)
这个方法来加载一个我们指定的xml
布局从而提供对话框内容。
public class EditNameDialogFragment extends DialogFragment
{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
View view = inflater.inflate(R.layout.fragment_edit_name, container);
return view;
}
}
【注】以上两种方法创建对话框时候只能使用其中一种,不能两个同时使用。
DialogFragment宽高设置无效
DialogFragment
在onCreate()
和onCreateView()
中设置布局大小无效,因为onCreate()
和onCreateView()
生命周期在onStart()
生命周期之前,此时还未调用Dialog.show()
方法,设置大小无效。所以要在onStart
方法中设置大小;
/**
* 修改布局的大小
*/
@Override
public void onStart() {
super.onStart();
resizeDialogFragment();
}
private void resizeDialogFragment() {
Dialog dialog = getDialog();
if (null != dialog) {
Window window = dialog.getWindow();
WindowManager.LayoutParams lp = getDialog().getWindow().getAttributes();
lp.height = (25 * ScreenUtil.getScreenHeight(getContext()) / 32);//获取屏幕的宽度,定义自己的宽度
lp.width = (8 * ScreenUtil.getScreenWidth(getContext()) / 9);
if (window != null) {
window.setLayout(lp.width, lp.height);
}
}
}
DialogFragment消失操作
DialogFragment
在正常Dismiss
后并不会直接从当前的栈中移除,而是在DialogFragment
中的onDestroyView()
回调时,才会对DialogFragment
进行出栈操作,所以如果你如果需要在Activity
中频繁的显示隐藏一个DialogFragment
,那么在dismiss
时需要手动的调用dismissAllowingStateLoss()
方法,并且再次show
时不能用上一个DialogFragment
实例。DialogFragment
并没有对Dialog
的消失提供监听给调用者使用,但是我们通过源码分析得知,DialogFragment
在onActivityCreate
当中其实已经帮我们设置了onDismissListener
,所以我们如果需要对Dialog
的消失进行监听的话只需重写onDismiss
方法即可,还有一种方式则是覆盖父类设置的onDismissListene
r监听,但是需注意的时,这个监听的复写,必须在父类onActivityCreate
方法调用之后。
关于消失监听的两种写法如下:
mListener
为提供到外部使用的回调 @Overridepublic void onDismiss(DialogInterface dialog) { super.onDismiss(dialog); mListener.onDismiss(dialog); Logger.d(TAG, "onDismiss"); }- 复写
setOnDismissListener
必须发生在父类的onActivityCreate
之后 @Overridepublic void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); if (getDialog() != null && null != mListener) { getDialog().setOnDismissListener(new DialogInterface.OnDismissListener() { @Overridepublic void onDismiss(DialogInterface dialog) { ToastUtils.showToast("覆盖后的OnDismiss Listener"); } }); } Logger.d(TAG, "onActivityCreated"); }