對話框經常作爲Activity的一部分來創建和顯示。你通常應該從protected Dialog Activity.onCreateDialog (int id) 回調方法裏創建對話框。當你使用這個回調函數時,Android系統會有效的設置這個Activity爲每個對話框的所有者,從而自動管理每個對話框的狀態並掛靠到Activity上。這樣,每個對話框繼承這個Activity的特定屬性。比如,當一個對話框打開時,菜單鍵顯示爲這個Activity定義的選項菜單,音量鍵修改Activity使用的音頻流。
- 注意: 如果你決定在onCreateDialog()方法之外創建一個對話框,它將不會被附着到活動上。不過,你可以通過setOwnerActivity(Activity)把它附着到一個活動上。
當你想要顯示一個對話框時,調用showDialog(int id) 方法並傳遞一個唯一標識這個對話框的整數。
當對話框第一次被請求時,Android從你的Activity中調用onCreateDialog(int id),你應該在這裏初始化這個對話框Dialog。這個回調方法被傳以和showDialog(int id)相同的ID。當你創建這個對話框後,在Activity的最後返回這個對象。
在對話框被顯示之前,Android還調用了可選的回調函數onPrepareDialog(int id, Dialog). 如果你想在每一次對話框被打開時改變它的任何屬性,你可以定義這個方法。這個方法在每次打開對話框時被調用,而onCreateDialog(int) 僅在對話框第一次打開時被調用。如果你不定義onPrepareDialog(),那麼這個對話框將保持和上次打開時一樣。這個方法也被傳遞以對話框的ID,和在onCreateDialog()中創建的對話框對象。(個人理解是,在本Activity裏第一次show某個Dialog,則先調用onCreateDialog,得到返回的Dialog對象並掛靠在Activity,保存Dialog對象的引用,然後才顯示Dialog。這樣子,下次再show Dialog就不用重新創建Dialog對象,而是重用舊的)
定義onCreateDialog(int) 和 onPrepareDialog(int, Dialog) 回調函數的最佳方法是使用一個switch 語句來檢查傳遞進來的id 參數。每個case 應該檢查一個唯一的對話框ID然後創建和定義相應的對話框。比如,想象一下一個遊戲使用兩個不同的對話框:一個用來指示這個遊戲已經暫停而另一個來指示遊戲結束。首先,爲每個對話框定義一個常量:
- static final int DIALOG_PAUSED_ID = 0;
- static final int DIALOG_GAMEOVER_ID = 1;
然後,爲每一個ID用一個switch case定義這個onCreateDialog(int) 回調函數:
- protected Dialog onCreateDialog(int id) {
- Dialog dialog;
- switch(id) {
- case DIALOG_PAUSED_ID:
- // do the work to define the pause Dialog
- break;
- case DIALOG_GAMEOVER_ID:
- // do the work to define the game over Dialog
- break;
- default:
- dialog = null;
- }
- return dialog;
- }
當是時候顯示其中之一的對話框時,使用對話框ID調用showDialog(int):
- showDialog(DIALOG_PAUSED_ID);
消除對話框Dismissing a Dialog
當你準備關閉對話框時,你可以通過對這個對話框調用dismiss()來消除它。如果需要,你還可以從這個Activity中調用dismissDialog(int id) 方法,這實際上將爲你對這個對話框調用dismiss() 方法。
如果你想使用onCreateDialog(int id) 方法來管理你對話框的狀態(就如同在前面的章節討論的那樣),然後每次你的對話框消除的時候,這個對話框對象的狀態將由該Activity保留。如果你決定不再需要這個對象或者清除該狀態是重要的,那麼你應該調用removeDialog(int id)。這將刪除任何內部對象引用而且如果這個對話框正在顯示,它將被消除。
使用消除偵聽器Using dismiss listeners
如果你希望你的應用程序在一個對話框消亡的時候執行一些流程,那麼你應該附着一個on-dismiss偵聽器到對話框上。
- @Override
- protected void onPrepareDialog(int id, Dialog dialog) {
- switch(id){
- case PROGRESS_DIALOG:
- dialog.setOnDismissListener(new DialogInterface.OnDismissListener(){
- @Override
- public void onDismiss(DialogInterface dialog) {
- Toast.makeText(getApplicationContext(),
- "dismiss listener!",
- Toast.LENGTH_SHORT)
- .show();
- }
- });
- }
- }
然而, 請注意對話框也可以被“取消”。這是一個表明對話框被用戶顯示取消的特殊情況。這將在用戶按“返回”按鈕時發生,或者這個對話框顯示的調用cancel() (也許通過對話框上的一個“取消”按鈕)。當一個對話框被取消時,這個OnDismissListener 依然會被通知到,但是如果你希望在對話框被顯示取消時被通知到(而不是通常的消除方式),那麼你應該通過setOnCancelListener()註冊一個DialogInterface.OnCancelListener 。
目前個人學習發現,一般情況下,調用dialog.cancel()就會觸發onCancelLister。而點擊AlertDialog的NegativeButton (Cancel/No)是不會觸發的。對於setOnCancelListener()要注意的是,這裏有兩個setOnCancelListener(),但返回值不同:
- //AlertDialog.Builder調用的
- public AlertDialog.Builder setOnCancelListener (DialogInterface.OnCancelListener onCancelListener)
- //Dialog調用的
- public void setOnCancelListener (DialogInterface.OnCancelListener listener)