接上篇,继续:
然后就是setShowsDialog(boolean showsDialog)方法。官方文档是这样解释的:控制DialogFragment是否是一个dislog,如果设置为false,则没有dialog被创建出来,你可以把它当做一个普通的Fragemnt使用。
开头提到了,mShowsDialog默认为true,所以如果你把DialogFragment确实作为一个Dialog使用,那大可不必调这个方法。当我看到OnCreate的方法时,就更加确定。(官方文档上说了一种情况,需要手动调用它,这种情况及其少见,有兴趣的可以自行去研究)。
public void setShowsDialog(boolean showsDialog) { mShowsDialog = showsDialog; }
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mShowsDialog = mContainerId == 0; if (savedInstanceState != null) { mStyle = savedInstanceState.getInt(SAVED_STYLE, STYLE_NORMAL); mTheme = savedInstanceState.getInt(SAVED_THEME, 0); mCancelable = savedInstanceState.getBoolean(SAVED_CANCELABLE, true); mShowsDialog = savedInstanceState.getBoolean(SAVED_SHOWS_DIALOG, mShowsDialog); mBackStackId = savedInstanceState.getInt(SAVED_BACK_STACK_ID, -1); } }mShowsDialog = mContainerId == 0;
没错,默认情况下,mContainerId就是0,所以mShowsDialog自然就是true;而当你在把它当成Fragment使用时,会为其指定xml布局中位置,所以,mContainerId也会不为0,所以mShowsDialog自然就是false。
然后是LayoutInflater getLayoutInflater(Bundle savedInstanceState),这个方法被hide了,所以外部是调不到的。
简单说一下这个getLayoutInflater方法,它的调用点是在onCreateView的时候,从先后顺序来说getLayoutInflater在onCreateView之前。
摘自FragmentManager:
f.mView = f.onCreateView(f.getLayoutInflater(f.mSavedFragmentState),null, f.mSavedFragmentState);
/** @hide */ @Override public LayoutInflater getLayoutInflater(Bundle savedInstanceState) { if (!mShowsDialog) { return super.getLayoutInflater(savedInstanceState); } mDialog = onCreateDialog(savedInstanceState); switch (mStyle) { case STYLE_NO_INPUT: mDialog.getWindow().addFlags( WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); // fall through... case STYLE_NO_FRAME: case STYLE_NO_TITLE: mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); } if (mDialog != null) { return (LayoutInflater) mDialog.getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE); } return (LayoutInflater) mActivity.getSystemService( Context.LAYOUT_INFLATER_SERVICE); }
STYLE_NO_FRAME和STYLE_NO_TITLE都调用了mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
那它们两个参数有什么不同呢,答案就在开头setStyle中,STYLE_NO_FRAME会再没有theme的情况下,设置theme为android.R.style.Theme_Panel。
然后就是onCreateDialog方法,你可以重写这个方法,创建一个自己定义好的dialog。默认情况下,会自己创建一个Dialog。
public Dialog onCreateDialog(Bundle savedInstanceState) { return new Dialog(getActivity(), getTheme()); }
public void onDismiss(DialogInterface dialog) { if (!mViewDestroyed) { dismissInternal(true); } }
@Override public void onStart() { super.onStart(); if (mDialog != null) { mViewDestroyed = false; mDialog.show(); } }
@Override public void onStop() { super.onStop(); if (mDialog != null) { mDialog.hide(); } }
@Override public void onDestroyView() { super.onDestroyView(); if (mDialog != null) { mViewDestroyed = true; mDialog.dismiss(); mDialog = null; } }
好了,以上就是DialogFragment源码部分。
小结:
1、DialogFragment本质上说就是Fragment,只是其内部还有一个dialog而已。你既可以当它是Dialog使用,也可以把它作为Fragment使用。
2、setStyle中,style的参数是不可以相互一起使用的,只能用一个,如果还不满足你使用,可以通过设置theme来满足。
3、setStyle的调用点,要放在onCreateView前,否则,设置的style和theme将不起作用!