目录(?)[-]

  1. 帮助提示框的实现
  2. 实现再弹框
  3. 再谈fragment管理器

提示框的按钮Help,将触发弹出新的帮助提示框。

帮助提示框的实现

帮助提示框的实现很简单,利用重写onCreateView( )的方式,点击按钮是执行dismiss(),关闭对话框即可。

代码不在此重复。dialog fragment的关闭有两种方式,一种是在dialog fragment中直接执行dismiss(),我们来看看DialogFragment的源代码片段:

[java] view plaincopy
 
  1. /** 
  2.  * Dismiss the fragment and its dialog.  If the fragment was added to the 
  3.  * back stack, all back stack state up to and including this entry will 
  4.  * be popped.  Otherwise, a new transaction will be committed to remove 
  5.  * the fragment. 
  6.  */  
  7. public void dismiss() {  
  8.     dismissInternal(false);  
  9. }  
  10.   
  11. void dismissInternal(boolean allowStateLoss) {  
  12.     if (mDismissed) {  
  13.         return;  
  14.     }  
  15.     mDismissed = true;  
  16.     mShownByMe = false;  
  17.     if (mDialog != null) {  
  18.         mDialog.dismiss();  
  19.         mDialog = null;  
  20.     }  
  21.     mViewDestroyed = true;  
  22.     if (mBackStackId >= 0) {  
  23.         getFragmentManager().popBackStack(mBackStackId,  
  24.                 FragmentManager.POP_BACK_STACK_INCLUSIVE);  
  25.         mBackStackId = -1;  
  26.     } else {  
  27.         FragmentTransaction ft = getFragmentManager().beginTransaction();  
  28.         ft.remove(this);   
  29.         if (allowStateLoss) {  
  30.             ft.commitAllowingStateLoss();  
  31.         } else {  
  32.             ft.commit();  
  33.         }  
  34.     }  
  35. }  

如果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开发相关文章