Dialog
在 fragment 没有出现之前,Dialog 是由 Activity 来管理的。
Activity 中有 onCreateDialog,showDialog 等几个方法,用于处理 dialog。
但现在这些方法都被抛弃了。
DialogFragment
现在,我们提倡使用 DialogFragment (以下简称 DF)。
DF 的出现将 Dialog 也融入到 Fragment 的生命周期中,统一管理。
DF 中有个成员 mDialog,所以用 DF 展示的对话框实质还是 Dialog。
为了保证 DF 和 mDialog 的状态始终是一致的(mDialog 显示时 DF 需要被 add 到 FragmentManger 中,mDialog dismiss 是 DF 则需要被 remove),
提倡不去直接操作该 Dialog,而是将通过 DF 的 API 来操作该 Dialog。
Style &Theme
public static final int STYLE_NORMAL = 0;
public static final int STYLE_NO_TITLE = 1;
public static final int STYLE_NO_FRAME = 2;
通过 setStyle 方法可以设置 DF 的样式和主题,第一种是默认,第二是无标题,第三是无背景和遮罩效果。
Show
public void show(FragmentManager manager, String tag) {
mDismissed = false;
mShownByMe = true;
FragmentTransaction ft = manager.beginTransaction();
ft.add(this, tag);
ft.commit();
}
还有一个重载的 show 方法,提供将事务放入回退栈的机会,我对撤销事务不感冒。
Dismiss
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();
}
}
}
DF 的实现中,始终在执行一点,就是保证 Dialog 和 DF 的状态一致性。
mDialog.dismiss 的同时 DF 也被 remove 了。
比之原生 Dialog 的优势
第一点,就是把 Dialog 融入到 fragment 的生命周期中了,但也有可能觉得这有点简单问题复杂化。(但开发人员都这么做,要相信他们的智谋和长远的眼光)
第二点,DF 重载的 onSaveInstanceState 函数,于是在旋转屏幕后 DF 的状态基本不会被破坏,而原生 Dialog 旋转后不会重新创建。
onCreateDialog onCreateView 自定义