您的位置:首页 > 移动开发 > Android开发

Pro Android学习笔记(四六):Dialog(3):对话框弹对话框

2013-10-29 16:13 351 查看
提示框的按钮Help,将触发弹出新的帮助提示框。

帮助提示框的实现

帮助提示框的实现很简单,利用重写onCreateView( )的方式,点击按钮是执行dismiss(),关闭对话框即可。
代码不在此重复。dialog fragment的关闭有两种方式,一种是在dialog fragment中直接执行dismiss(),我们来看看DialogFragment的源代码片段:
/**
     * Dismiss the fragment and its dialog.  If the fragment was added to the
     * back stack, all back stack state up to and including this entry will
     * be popped.  Otherwise, a new transaction will be committed to remove
     * the fragment.
     */
    public void dismiss() {
        dismissInternal(false);
    }
    
    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();
            }
        }
    }

如果back stack堆栈有该dialog,将其pop出来,否则ft.remove(this); ft.commit();。估计pop的操作也包含ft.remove()和ft.commit()。调用dismiss()会触发onDismiss()回调函数。跟踪状态,如下。



实现再弹框

在PromptDialogFragment中实现弹框的相关代码如下。这里采用另一种关闭dialog的方法,通过fragment transaction进行控制。

public void onClick(View v) {

... ...

switch(v.getId()){

case R.id.button_help:

FragmentTransaction ft = getFragmentManager().beginTransaction();




/* 如果不执行remove(),prompt dailog在下层,跟踪状态,系统即不会进入onDismiss()状态。主要考虑美观的问题,如果下面prompt对话框大于帮助框,视觉效果不好。下面左图为执行了remove()的效果,右图为不执行remove()的效果。

对于Dialog,container为0或者null。 */

ft.remove(this);

/* 将当前的PromptDialogFragment加入到回退堆栈,当用户按返回键,或者通过按帮助框的Close按钮dismiss帮助框是,重新显示提示框。


对于back stack的处理,系统具有一定的智能。例如:执行两次addToStackStack(),实际不会重复压栈。 有例如:注释掉remove()语句,即提示框不消失,而是在帮助框的下面,如右图,由于提示框存在,我们并不需要将提示框键入到back stack,但是在实验中发现是否有addToBackStack()都不会结果有影响,系统能够分析到对象存在,不需要压栈。没有去查源代码,猜测通过mBackStackId比对来进行智能处理。*/

ft.addToBackStack(null);



HelpDialogFragment hdf = HelpDialogFragment.newInstance(R.string.help_message);

/* 对fragment的处理是通过fragment transaction,与在activity弹框一样,通过show()方式实现。 在此之前,我们已经通过transaction将当前的fragment加入到back stack中。*/

hdf.show(ft,MainActivity.HELP_DIALOG_TAG);


break;

... ...

}

}
通过remove()和addToBackStack()使得fragment从UI中消失,当仍可以通过fragment管理器和回退堆栈获取。

再谈fragment管理器

通过fragment管理器或者fragment transaction,我们可以对dialog fragment进行具体地控制。show()就是在管理器中加入fragment,dismiss()就是从管理器中去掉fragment。我们不能先进行add(),然后在进行show(),因此一个fragment对象只能加入管理器一次。如果fragment被dismiss(),将从管理器中删除,我们不能再通过管理器获取该fragment的信息。因此,如果我们想保留被dismiss的dialog的一些状态或信息,需要在dialog外进行保存,例如利用activity。

本博文涉及的例子代码,可以在Pro Android学习:Dialog小例子中下载。

相关链接:
我的Android开发相关文章
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: