Android中Dialog

來源:互聯網
上載者:User

在Android中,Dialog是一個非常重要的UI, 它可以方便的給使用者提示,用最簡潔的方式向使用者展示資訊, 以下的圖片是Dialog的一個整體架構,通過它,可以總體對Dialog有一個很清晰的認識. 

從這張圖中可以看到,Dialog為父類, 其下有最重要的, 我們最常用的AlertDilog, 而AlertDialog的子類,則是由DatPicker, ProgressDialog,TimePick來組成. 
這幾個子類都是我們在程式開發中最常用的,因此要重點理解, 我們可以試著想像一下,如下幾個問題的答案 
<1> 怎麼產生一個Dialog? 
<2> Dialog與Activity是什麼關係? 為什麼顯示Dialog的時候,Activity就失去了焦點,不能被點擊,在系統內部到底是怎麼管理他們的關係的? 

我們以ProgressDialog為例, 通過分析其源碼,讓我們徹底理解它的內部運行機制 

<1> 怎麼產生一個ProgressDialog? 
    通過開啟ProgressDialog的源碼, 可以看到它有2個構造方法, 
    
     ProgressDialog(Context context) 

     ProgressDialog(Context context,int theme) 

  參數解釋: context:說明它是依靠Context,必須通過一個Context來建立它, 第二個參數theme: 此dialog的主題. 

    另外我們還可以發現  有四個靜態show方法,他們只是參數不同, 

     show(Context context,CharSequence title,CharSequence message); 

     show(Context context,CharSequence title,CharSequence message,boolean indeterminate); 

其時,我們只看最後一個靜態方法就行了,因為三個靜態方法,最終會調用最後一個參數最多的show靜態方法來完成功能. 

它所實現的功能是: 
     ProgressDialog dialog=new ProgressDiaog(context); 
     ... 
     ... 
     ... 
     dialog.show(); 

這其實跟,我們調用構造方法是一樣的. 

到這一步,僅僅是知道了,怎麼調用產生的ProgressDialog的,但具體內部的細節呢。還要看onCreate()方法, 此方法才是真正能產生progressDialogr 地方, 它跟Activity中的onCreate()方法是一樣的,就是初始化的時候調用, 我們看其源碼如下: 

首先看到的是一個名叫 mViewUpdatehandler的 Handler, 這個Handler主要用來更新progress的值, (百分比),接著往下看... 
有這麼一句: View view=inflater.inflate(R.layout.alert_dialog_press,null); 
很明顯,這就是我們看到的,顯示在dialog中轉圈的那個東東. 然而,這個alert_dialog_pross檔案是在com.android.internal.R 包中,屬於系統定義的ui設定檔. 

最後調用 setView(view)方法來, 來把view顯示在Dialog上。 

因此,我們同樣也可以實現自訂一個dialog.xml檔案,來調用setView()方法顯示上來. 

這個setView()方法是AlertDialog類中定義的,等會再解釋! 

這就是我們平時所見到的 ProgressDialog。分析完畢。 

AlertDialog 

接下來,我們開始分析ProgressDialog的父類  AlertDialog. 

開啟源碼,首先映入眼帘的是 三個構造方法,但這三個構造方法都是protected類型的, 
可見,不允許我們直接執行個體化AlertDialog. 因此,我們再看別的有沒有方法.可以執行個體化 

再仔細一看,發現一個變數 , 

   AlertController mAlert; 這個才是我們今天的主角,重點研究它. 

   mAlert的定義是在 ,以上我們提到的AlertDialog的建構函式, 

此外,我們還發現,AlertDialog中幾乎所有的方法都是通過這個mAlert變數來操作的, 

也就是說,AlertDialog是一個空殼,並沒有實際的作用, 它的實質是AlertController類. 
就是我剛才說的  "主角" 。 而Alertcontroller的源碼,是Android系統內建的,我們需要花費一番力氣去尋找. 

在往下看,AlertDialog 類中,發現一個靜態類 Builder,  通過這個類,我們也可以直接建立一個Dialog, 
Builder靜態類中也同樣有一個AlertController.Alertparams的類的對象 P,我們再看Builder的源碼,它裡面可以設定所有Dialog的的方法,包括 
setTitle(CharSequence title) 
setMessage(int messageId); 
setIcon(int iconId); 
setPositiveButton() 
  ... 
  ... 
  .... 

等,我們看這些方法的的內部實現,全部是針對它的內建對象P 來實現的, 也就是我們所調用的這些方法,最終結果實際上是用在了AlertController.AlertParams 類的對象P 身上, 

,而別外還有一個有趣的現象,這些方法的傳回值都是Builder對象, 也就是說,我們可以連級調用此方法, 

而顯示一個Dialog,僅僅調用這些set 方法,還不夠,最後還差一步, 就是調用create()方法,這個方法是最後調用的,也就是建立對話方塊, 我們看,create方法中都做了那些動作 

public AlertDialog create() { 
   final AlertDialog dialog =new AlertDialog(p.mContext); 
   p.apply(dialog.mAlert) 
   dialog.setCancelable(P.mCancelable); 
   
   return dialog; 

這個是create()的實現,我們可以很直觀地看出是它幫我們建立了一個AlertDialog對象, 
這裡的p, 就是我們建立的AlertController.Alertparams的對象, 
而在AlertDialog  dialog=new AlertDialog(p.mContext); 這句代碼中,定義Dialog的同時也定義了 一個AlertController 的對象 mAlert; 

在第二句代碼中,p.apply(dialog.mAlert) ,我們跟蹤過去,看下,哈哈,原來是,我們剛才調用的set方法的值,又還原給新定義的dialog中的  mAlert對象了,  這下明白了,原來 P只不過是一個 "屁"   ,暫時的存放資料的對象,只要我們調用create方法,P就會乖乖的把資料交給dialog對象, 

除了create方法以外, 還有一個show() 方法,實現如下 

public AlertDialog show() { 
    AlertDialog dialog=create(); 
    dialog.show(); 
    return dialog; 

我們可以看出,show() 也是調用的 create方法. 
由以下的分析,我們就可能輕鬆理解,如下我們常用的語句了, 

return new AlertDialog.Builder(context). 
            setIcon(R.drawable.alert_icon). 
            setTitle(R.string.alert_str) 
            .create() ; 

這是我們平時用到的產生Dialog 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.