展会信息港展会大全

Android编程之DialogFragment源码详解(二)
来源:互联网   发布日期:2015-09-29 10:58:40   浏览:726次  

导读:接上篇,继续:然后就是setShowsDialog(boolean showsDialog)方法。官方文档是这样解释的:控制DialogFragment是否是一个dislog,如果设置为f...

接上篇,继续:

然后就是setShowsDialog(boolean showsDialog)方法。官方文档是这样解释的:控制DialogFragment是否是一个dislog,如果设置为false,则没有dialog被创建出来,你可以把它当做一个普通的Fragemnt使用。

开头提到了,mShowsDialog默认为true,所以如果你把DialogFragment确实作为一个Dialog使用,那大可不必调这个方法。当我看到OnCreate的方法时,就更加确定。(官方文档上说了一种情况,需要手动调用它,这种情况及其少见,有兴趣的可以自行去研究)。

public void setShowsDialog(boolean showsDialog) {

mShowsDialog = showsDialog;

}

来看onCreate方法:@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);

getLayoutInflater方法如下:/** @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);

}

如果不是Dialog,则调用Fragment自身的方法;否则,就先创建一个dialog,然后,根据之前设置的style,对dialog赋值。所以,setStyle这个方法调用,一定要在onCreateView之前。一般来讲,都会放到onCreate中调用。

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());

}

再说一个onDismiss方法,没错,它是DialogInterface.OnDismissListener中的方法,DialogFragment实现了它。所以,在dialog不显示后,会回调这个方法,然后再去调用自己的dismissInternal方法:public void onDismiss(DialogInterface dialog) {

if (!mViewDestroyed) {

dismissInternal(true);

}

}

那么,dialog什么时候显示出来?是在OnStart的时候:@Override

public void onStart() {

super.onStart();

if (mDialog != null) {

mViewDestroyed = false;

mDialog.show();

}

}

而与其对应的生命周期方法onStop()时,则是将其先隐藏了。@Override

public void onStop() {

super.onStop();

if (mDialog != null) {

mDialog.hide();

}

}

最后就是onDestroyView方法,它会将dialog销毁。@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将不起作用!

赞助本站

人工智能实验室

相关热词: android开发 教程

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港