DialogFragment是Fragment家族成员之一,如果你把它简单的理解成Dialog,那就错了。它的确可以做作dialog显示,还可以显示出自己定义的Dialog或者AlertDialog,但它同时也是一个Fragment。
按照官方的话来理解就是,你既可以把它当成一个dialog显示出来,也可以让它作为一个Fragment嵌套在Activity中,这样更方便开发。
为什么这么说呢?试想一下,当产品需求最开始把它作为一个界面显示的时候,你可能已经把它作为Fragment已经写好了,但中途产品又把它设计成一个dialog,那你该怎么办?重新去一个dialog或者activity吗?以前的传参怎么办?过两天,产品又将它改回去,你还要再重写一遍吗?等等一系列的问题就来了。
所以,这个时候,你只需要把当前的Fragment继承类改为DialogFragment,再添加几行代码就可以了。其他的,基本都不用动。即使过两天再改回来,或者别的界面也需要它的时候,你就可以直接把它当做Fragment,继续使用,代码都不用改。
这一点,不得不赞一下Fragment这个的出现,大大方便了开发,再也不怕产品设计调整界面布局了!
这里多啰嗦一句,如果产品已经定义好了作为dialog,或者之前就是dialog的,就不要将它们改成DialogFragment的了,还是那句话:只做有意义的代码改动!
DialogFragment的使用用例,官方文档已经写得很清楚了,Demo例子也有,在androidSDK的sample文件夹中,有需要的请自行查阅。
今天之所以翻出源码来,主要还是希望通过对代码的了解,更好使用DialogFragment。而且有些细节部分,不看源码的话,可能就真在方法传值时传错了。比如:style的设置!
在源码最开始部分,就定义了style的常量:
public static final int STYLE_NORMAL = 0;
public static final int STYLE_NO_TITLE = 1;
public static final int STYLE_NO_FRAME = 2;
public static final int STYLE_NO_INPUT = 3;
STYLE_NORMAL:会显示一个普通的dialog
STYLE_NO_TITLE:不带标题的dialog
STYLE_NO_FRAME:无框的dialog
STYLE_NO_INPUT:无法输入内容的dialog,即不接收输入的焦点,而且触摸无效。
说起来,android很多参数的设置,都有用到“|”的方法,表示支持两种或两种以上。最常见的,就是“Top|Left”,所以,在这里有很多人会想用吧:STYLE_NO_TITLE|STYLE_NO_INPUT。那你可就错了,这么用的结果就是把style设置成了:STYLE_NO_INPUT ( 因为:1 | 3 = 3 )
接下来,再看一下它的内部变量:
int mStyle = STYLE_NORMAL;
int mTheme = 0;
boolean mCancelable = true;
boolean mShowsDialog = true;
int mBackStackId = -1;
Dialog mDialog;
boolean mViewDestroyed;
boolean mDismissed;
boolean mShownByMe;
mStyle:默认的样式为STYLE_NORMAL;
mTheme:主题,默认没有设置,而是在setStyle(int style, int theme) 方法中,对其初始化设置,下面会讲到;
mCancelable:是否可以取消,默认是ture,实际上就是设置给Dialog的mDialog.setCancelable(mCancelable);
mShowsDialog:这个参数我放到下面去讲,默认也为true
mBackStackId:后退栈的ID,也就是说,当DialogFragment不显示时,会清空栈里的数据。(关于后退栈的问题,请留心我后面关于FragmentManager详解的文章);
mDialog:DialogFragment之所以会以窗口方式显示,实际上就是其内部有一个Dialog,也就是它,上面的样式、主题、可取消都是设置给它的;
后面三个boolean的变量,就是标志位:
mViewDestroyed:标志位,在Dialog不显示时,处理Fragment的移除操作;
mDismissed:标志位,Dialog是否不显示了;
mShownByMe:标志位,在Dialog是否显示,和mDismissed基本是一对;
DialogFragment的构造方法是空的,什么也没有:
public DialogFragment() {
}
然后就是setStyle方法:
public void setStyle(int style, int theme) {
mStyle = style;
if (mStyle == STYLE_NO_FRAME || mStyle == STYLE_NO_INPUT) {
mTheme = android.R.style.Theme_Panel;
}
if (theme != 0) {
mTheme = theme;
}
}
开头已经讲过了,style使用注意事项。通过这个方法,可以看到,在不设置theme,即为0的情况下,theme会被设置为android.R.style.Theme_Panel。
这还可以根据自己定义的Dialog样式设置进来。
下面就是show方法,共有两个:
public void show(FragmentManager manager, String tag) {
mDismissed = false;
mShownByMe = true;
FragmentTransaction ft = manager.beginTransaction();
ft.add(this, tag);
ft.commit();
}
public int show(FragmentTransaction transaction, String tag) {
mDismissed = false;
mShownByMe = true;
transaction.add(this, tag);
mViewDestroyed = false;
mBackStackId = transaction.commit();
return mBackStackId;
}
虽然是两种写法,但实际上还是将自己添加到FragmentManager中而已。
有显示,就是得有不显示的代码:
public void dismiss() {
dismissInternal(false);
}
public void dismissAllowingStateLoss() {
dismissInternal(true);
}
两个方法都是调用了void dismissInternal(boolean allowStateLoss),只是传参不一样而已,看一下dismissInternal这个方法:
void dismissInternal(boolean allowStateLoss) {
if (mDismissed) {
return;
}
mDismissed = true;
mShownByMe = false;
if (mDialog != null) {
mDialog.dismiss();
mDialog = null;
}
mViewDestroyed = true;
if (mBackStackId >= 0) {
getFragmentManager().popBackStack(mBackStackId,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
mBackStackId = -1;
} else {
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.remove(this);
if (allowStateLoss) {
ft.commitAllowingStateLoss();
} else {
ft.commit();
}
}
}
它做了几件事:
1、调用dialog的dismiss方法
2、如果自己在后退栈中,就将自己从后退栈中移除掉(弹出)
3、如果自己不在后退栈中,就将自己从FragmentManager中移除掉。
关于commitAllowingStateLoss与commit的区别,网上有很多讲解,这里也不细说了。以后的FragmentManager中,会对它有更详细的解释。
今天就先写到这里,后面部分下次发布。
分享到:
相关推荐
类似PopupWindow的弹框DialogFragment实现TabLayout+ViewPager多个Fragment左右滑动切换
相关博客:【android学习开源项目之AndroidAutoSize】AndroidAutoSize和DialogFragment的适配 https://blog.csdn.net/ljb568838953/article/details/103906449; 本demo的知识点:1.AndroidAutoSize 的使用(今日...
blog原文 http://blog.csdn.net/qiaoidea/article/details/46402845 讲解分析 Dialog 和DialogFragment
本文实例讲述了Android开发之DialogFragment用法。分享给大家供大家参考,具体如下: 背景 Android 官方推荐使用 DialogFragment 来代替 Dialog ,可以让它具有更高的可复用性(降低耦合)和更好的便利性(很好的...
关于详解Android应用中DialogFragment的基本用法,大家可以参考下。 1、 概述 DialogFragment在android 3.0时被引入。是一种特殊的Fragment,用于在Activity的内容之上展示一个模态的对话框。典型的用于:展示警告框...
使用建造者模式、dialogfragment、recycleView自定义列表式的dialog
博客地址:http://blog.csdn.net/krubo1/article/details/50462048
Android DialogFragment的使用方法 ,google官方推荐使用DialogFragment代替Dialog. 具体的详细解释可以在我的博客http://blog.csdn.net/a253664942/article/details/45585661中看看,有问题的可以我给留言!
DialogFragment实现底部弹窗 DialogFragment底部弹窗的开发模板,Created by C.L. Wang
Android 使用DialogFragment 实现一个可以多选的Dialog,实现横竖屏切换动态设置界面大小,轻松实现你想要的效果。
android 自定义dialogfragment全屏对话窗体,这个demo还是很棒的。值得学习,直接用在项目里。
Android弹窗实现之Popupwindow及DialogFragment。创建并实现PopupWindow布局 实现PopupWindow对象实例 设置PopupWindow背景、动画属性、控件实现及事件监听 显示PopupWindow及位置设定。
android当中DialogFragment的简单使用,配合博客的代码
android-dialogfragment Android DialogFragment 示例
DialogFragment的基本用法 1. 创建DialogFragment public class DialogA extends DialogFragment implements DialogInterface.OnClickListener { @Override public Dialog onCreateDialog(Bundle ...
本实例尽量做到实现该功能的最小实例,换句话说就是,尽量去掉与实现该功能无法的代码从而使我们更容易的看到实现该功能的核心。
Android中基于DialogFragment实现的Dialog提示功能,附加了nice的动画效果。
Android很好用的确认对话框(DialogFragment)