DialogFragment继承自Fragment,原本以为弹窗就是个Fragment,看过资源后没想到它里面还有一个Dialog,真的是很惊喜和很意外,那么它就是个Dialog,官方为啥建议用DialogFragment呢?是不是有毛病?
先来看一下源码,DialogFragment显示的时候是调用的show方法,代码如下:
public void show(@NonNull FragmentManager manager, @Nullable String tag) {
mDismissed = false;
mShownByMe = true;
FragmentTransaction ft = manager.beginTransaction();
ft.add(this, tag);
ft.commit();
}
没啥特别的,就是把Fragment加入到管理栈里面,然后就进行Fragment的生命周期方法调用,如下:在onActivityCreated方法里面设置了Dialog的view是否可取消等等一些属性
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (!mShowsDialog) {
return;
}
View view = getView();
if (view != null) {
if (view.getParent() != null) {
throw new IllegalStateException(
"DialogFragment can not be attached to a container view");
}
mDialog.setContentView(view);
}
final Activity activity = getActivity();
if (activity != null) {
mDialog.setOwnerActivity(activity);
}
mDialog.setCancelable(mCancelable);
mDialog.setOnCancelListener(this);
mDialog.setOnDismissListener(this);
if (savedInstanceState != null) {
Bundle dialogState = savedInstanceState.getBundle(SAVED_DIALOG_STATE_TAG);
if (dialogState != null) {
mDialog.onRestoreInstanceState(dialogState);
}
}
}
而Dialog的创建是在onGetLayoutInflater中创建,如下:
public LayoutInflater onGetLayoutInflater(@Nullable Bundle savedInstanceState) {
if (!mShowsDialog) {
return super.onGetLayoutInflater(savedInstanceState);
}
mDialog = onCreateDialog(savedInstanceState);
if (mDialog != null) {
setupDialog(mDialog, mStyle);
return (LayoutInflater) mDialog.getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
}
return (LayoutInflater) mHost.getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
}
而onGetLayoutInflater是在onCreateView里面调用的,然后进行onCreateDialog方法的调用创建Dialog
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
return new Dialog(requireContext(), getTheme());
}
创建完之后在Fragment的onStart方法中将Dialog显示出来,如下所示:
@Override
public void onStart() {
super.onStart();
if (mDialog != null) {
mViewDestroyed = false;
mDialog.show();
}
}
@Override
public void onStop() {
super.onStop();
if (mDialog != null) {
mDialog.hide();
}
}
在Fragment的stop方法中将dialog显示隐藏,在onDestroyView方法中将dialog彻底的关闭
@Override
public void onDestroyView() {
super.onDestroyView();
if (mDialog != null) {
// Set removed here because this dismissal is just to hide
// the dialog -- we don't want this to cause the fragment to
// actually be removed.
mViewDestroyed = true;
// Instead of waiting for a posted onDismiss(), null out
// the listener and call onDismiss() manually to ensure
// that the callback happens before onDestroy()
mDialog.setOnDismissListener(null);
mDialog.dismiss();
if (!mDismissed) {
// Don't send a second onDismiss() callback if we've already
// dismissed the dialog manually in dismissInternal()
onDismiss(mDialog);
}
mDialog = null;
}
}
看完源码可知,其实DialogFragment就是包裹了Dialog,让Dialog有了Fragment的生命周期,可以适当减少开发者对Dialog必须的打开和关闭的控制。其他方面它就是个Dialog