鸿 网 互 联 www.68idc.cn

当前位置 : 主页 > 网络程序脚本 > linux shell > >

关于Android里的Dialog

来源:互联网 作者:佚名 时间:2015-06-03 08:52
由做Android应用到做Android手机也有些时间了 总是觉得自己成长的太慢 后仔细想来 自己没有好好总结 学而不思则罔 今天就来好好总结下Android里面的Dialog 相信大家 都对用Dialog十分熟悉 有两种方法 一种是在Activity里调用showDialog(int) 然后在Dialog on

  由做Android应用到做Android手机也有些时间了总是觉得自己成长的太慢

  后仔细想来自己没有好好总结学而不思则罔今天就来好好总结下Android里面的Dialog

  相信大家都对用Dialog十分熟悉有两种方法

  一种是在Activity里调用showDialog(int)然后在Dialog onCreateDialog里创建Dialog返回交由Activity来管理

  一种是自己直接用AlertDialogBuilder自己Create然后自己调用show()然后显示

  我把话先说在前头建议用第一种方法去做这会让你省去很多麻烦因为Activity已经帮我们管理Dialog做了很多有用的事情

  还有几个很重要的概念相信大家都也应该清楚

   我们所有的应用程序所用到的dialog都是继承自AlertDialog的包括ProgressDialogTimePickerDialogDatePickerDialog等

   Dialog不同于Activity它有自己的Window

  接下来我们从两种创建Dialog方法来分析吧以ProgressDialog为例

  首先我们来看下ProgressDialog显示出来的几个部分吧

  总的来说分三部分

   MessageTitle

   进度条显示百分比的字符等

  下面被隐藏的Button

  为什么这么说呢请跟我看代码从第一种方法说起即ActivitShowDialog(int)



publicfinalvoid showDialog(int id) {  
        showDialog(id null);  
    }  
publicfinalboolean showDialog(int id Bundle args) {  
if (mManagedDialogs == null) {  
            mManagedDialogs = new SparseArray<ManagedDialog>();  
        }  
        ManagedDialog md = mManagedDialogsget(id);  
if (md == null) {  
            md = new ManagedDialog();  
            <span style=color:#;>mdmDialog = createDialog(id null args);</span>  
if (mdmDialog == null) {  
returnfalse;  
            }  
            mManagedDialogsput(id md);  
        }  

        mdmArgs = args;  
<span style=color:#;>        onPrepareDialog(id mdmDialog args);  
        mdmDialogshow();</span>  
returntrue;  
    }  
private Dialog createDialog(Integer dialogId Bundle state Bundle args) {  
        <span style=color:#;>final Dialog dialog = onCreateDialog(dialogId args);</span>  
if (dialog == null) {  
returnnull;  
        }  
        <span style=color:#;>dialogdispatchOnCreate(state);</span>  
return dialog;  
    }  这里面可以很明显的看出来Activity首先去列表里面去查找看这个id的Dialog是否创建过不存在就先调用createDialog()创建dialog否则就直接调用了onPrepareDialog最后调用show()(这里面有文章放在后面讲)

  我们也可以看到在createDialog里面先调用了onCreateDialog()拿到dialog对象然后去触发dialog的onCreate函数

  这里一直没发现我们设置的一些参数setMessagesetTitlesetButton去哪儿了我们去ProgressDialogonCreate看看吧

  

protectedvoid onCreate(Bundle savedInstanceState) {  
        LayoutInflater inflater = LayoutInflaterfrom(mContext);  
if (mProgressStyle == STYLE_HORIZONTAL) {  

/* Use a separate handler to update the text views as they
             * must be updated on the same thread that created them
             */
            mViewUpdateHandler = new Handler() {  
@Override
publicvoid handleMessage(Message msg) {  
superhandleMessage(msg);  

/* Update the number and percent */
int progress = mProgressgetProgress();  
int max = mProgressgetMax();  
double percent = (double) progress / (double) max;  
                    String format = mProgressNumberFormat;  
                    mProgressNumbersetText(Stringformat(format progress max));  
                    SpannableString tmp = new SpannableString(mProgressPercentFormatformat(percent));  
                    tmpsetSpan(new StyleSpan(AndroidgraphicsTypefaceBOLD)  
 tmplength() SpannableSPAN_EXCLUSIVE_EXCLUSIVE);  
                    mProgressPercentsetText(tmp);  
                }  
            };  
            View view = inflaterinflate(Rlayoutalert_dialog_progress null);  
            mProgress = (ProgressBar) viewfindViewById(Ridprogress);  
            mProgressNumber = (TextView) viewfindViewById(Ridprogress_number);  
            mProgressNumberFormat = %d/%d;  
            mProgressPercent = (TextView) viewfindViewById(Ridprogress_percent);  
            mProgressPercentFormat = NumberFormatgetPercentInstance();  
            mProgressPercentFormatsetMaximumFractionDigits();  
            <span style=color:#FF;>setView(view);</span>  
        } else {  
            View view = inflaterinflate(Rlayoutprogress_dialog null);  
            mProgress = (ProgressBar) viewfindViewById(Ridprogress);  
            mMessageView = (TextView) viewfindViewById(ssage);  
            <span style=color:#FF;>setView(view);</span>  
        }  
  
        setIndeterminate(mIndeterminate);  
        onProgressChanged();  
superonCreate(savedInstanceState);  

  



public Builder setView(View view) {  
PmView = view;  
    PmViewSpacingSpecified = false;  
returnthis;  
}  

可以看到ProgresDialog只是做了个主要setView()实际上就是给mView赋值然后调用父类AlertDialog的onCreate也来看看吧

  

protectedvoid onCreate(Bundle savedInstanceState) {  
superonCreate(savedInstanceState);  
        mAlertinstallContent();  
    }  
进入AlertController  
publicvoid installContent() {   
/* We use a custom title so never request a window title */
        mWindowrequestFeature(WindowFEATURE_NO_TITLE);  

if (mView == null || !canTextInput(mView)) {  
            mWindowsetFlags(WindowManagerLayoutParamsFLAG_ALT_FOCUSABLE_IM  
                    WindowManagerLayoutParamsFLAG_ALT_FOCUSABLE_IM);  
        }  
mWindowsetContentView(comandroidinternalRlayoutalert_dialog);  
        setupView(); 
    }  
privatevoid setupView() {  
        LinearLayout contentPanel = (LinearLayout) mWindowfindViewById(ntentPanel);  
        setupContent(contentPanel);  
boolean hasButtons = setupButtons(); 

        LinearLayout topPanel = (LinearLayout) mWindowfindViewById(RidtopPanel);  
        TypedArray a = mContextobtainStyledAttributes(  
null comandroidinternalRstyleableAlertDialog comandroidinternalRattralertDialogStyle );  
boolean hasTitle = setupTitle(topPanel); 

        View buttonPanel = mWindowfindViewById(RidbuttonPanel);  
if (!hasButtons) {  
            buttonPanelsetVisibility(ViewGONE);  
        }  

        FrameLayout customPanel = null;  
if (mView != null) {  
            customPanel = (FrameLayout) mWindowfindViewById(RidcustomPanel);  
            FrameLayout custom = (FrameLayout) mWindowfindViewById(Ridcustom);  
customaddView(mView new LayoutParams(MATCH_PARENT MATCH_PARENT)); 
if (mViewSpacingSpecified) {  
                customsetPadding(mViewSpacingLeft mViewSpacingTop mViewSpacingRight  
                        mViewSpacingBottom);  
            }  
if (mListView != null) {  
                ((LinearLayoutLayoutParams) customPanelgetLayoutParams())weight = ;  
            }  
        } else {  
            mWindowfindViewById(RidcustomPanel)setVisibility(ViewGONE);  
        }  

/* Only display the divider if we have a title and a 
         * custom view or a message
         */
if (hasTitle && ((mMessage != null) || (mView != null))) {  
            View divider = mWindowfindViewById(RidtitleDivider);  
            dividersetVisibility(ViewVISIBLE);  
      
看到了吗?我们前面的mView只是整个Dialog的一部分而已   

好了我们来总结下这第一种创建方法的顺序吧showDialog()>createDialog()>onCreateDialog()>onCreate()>setupView()>onPrepareDialog()>show()

  接下来我们再来看看第二创建方法吧

  

 AlertDialogBuilder builder = new Builder(Mainthis);  
 buildersetMessage(确认退出吗?);  
 buildersetTitle(提示);  
 buildersetPositiveButton(确认 new OnClickListener() {  
@Override
publicvoid onClick(DialogInterface dialog int which) {  
   dialogdismiss();  
   Mainthisfinish();  
  }  
 });  
 buildersetNegativeButton(取消 new OnClickListener() {  
@Override
publicvoid onClick(DialogInterface dialog int which) {  
   dialogdismiss();  
  }  
 });  
 buildercreate()show();  

  



public AlertDialog create() {  
final AlertDialog dialog = new AlertDialog(PmContext);  
           Papply(dialogmAlert);  
           dialogsetCancelable(PmCancelable);  
           dialogsetOnCancelListener(PmOnCancelListener);  
if (PmOnKeyListener != null) {  
               dialogsetOnKeyListener(PmOnKeyListener);  
           }  
return dialog;  
       }  

  看到没有create完直接调show()

  那我不知道你们没有同样的疑问像我们第一种方法里像TitleMessagemView都是在AlertDialog的onCreate()里面放进去的那我们又没有调用onCreate()函数他们最后是怎样显示出来的呢?

  呵呵我们最后来看看

  

buildercreate()产生的是AlertDialog对象但它自己没有定义show()最后调到了Dialogshow()  
publicvoid show() {  
if (mShowing) {  
if (mDecor != null) {  
                mDecorsetVisibility(ViewVISIBLE);  
            }  
return;  
        }  

if (!mCreated) {  
            dispatchOnCreate(null);  
        }  

        onStart();  
        mDecor = mWindowgetDecorView();  
        WindowManagerLayoutParams l = mWindowgetAttributes();  
if ((lsoftInputMode  
                & WindowManagerLayoutParamsSOFT_INPUT_IS_FORWARD_NAVIGATION) == ) {  
            WindowManagerLayoutParams nl = new WindowManagerLayoutParams();  
            pyFrom(l);  
            nlsoftInputMode |=  
                    WindowManagerLayoutParamsSOFT_INPUT_IS_FORWARD_NAVIGATION;  
            l = nl;  
        }  

try {  
           mWindowManageraddView(mDecor l) 
            mShowing = true;  

           sendShowMessage();
        } finally {  
        }  
    }  

看到这里为什么Tiltemessage为什么会出现知道了吧
第二种方法的流程是这样的
show()>onCreat()>setupView()


总算简要的分析完了
提个问题如果你想修改Dialogtitle的字体是不是只能在onPrepareDialog()里面来做啊?第二种方法是不是做不到啊?
网友评论