轉(zhuǎn)自:http://android.blog.51cto.com/268543/333769/
本文是對網(wǎng)上的文章《Android開發(fā)指南-用戶界面-對話框》的部分內(nèi)容進(jìn)行簡化吧黄,并加上自己的某些理解越除。里面的相同內(nèi)容,版權(quán)歸原翻譯作者所有肿轨。
顯示對話框
對話框經(jīng)常作為Activity的一部分來創(chuàng)建和顯示。你通常應(yīng)該從protected Dialog?Activity.onCreateDialog (int id)回調(diào)方法里創(chuàng)建對話框喻杈。當(dāng)你使用這個回調(diào)函數(shù)時勾栗,Android系統(tǒng)會有效的設(shè)置這個Activity為每個對話框的所有者,從而自動管理每個對話框的狀態(tài)并掛靠到Activity上贷洲。這樣收厨,每個對話框繼承這個Activity的特定屬性。比如优构,當(dāng)一個對話框打開時诵叁,菜單鍵顯示為這個Activity定義的選項菜單,音量鍵修改Activity使用的音頻流钦椭。
注意:?如果你決定在onCreateDialog()方法之外創(chuàng)建一個對話框拧额,它將不會被附著到活動上。不過彪腔,你可以通過setOwnerActivity(Activity)把它附著到一個活動上侥锦。
當(dāng)你想要顯示一個對話框時,調(diào)用showDialog(int id)方法并傳遞一個唯一標(biāo)識這個對話框的整數(shù)德挣。
當(dāng)對話框第一次被請求時恭垦,Android從你的Activity中調(diào)用onCreateDialog(int id),你應(yīng)該在這里初始化這個對話框Dialog格嗅。這個回調(diào)方法被傳以和showDialog(int id)相同的ID番挺。當(dāng)你創(chuàng)建這個對話框后,在Activity的最后返回這個對象屯掖。
在對話框被顯示之前玄柏,Android還調(diào)用了可選的回調(diào)函數(shù)onPrepareDialog(int id, Dialog). 如果你想在每一次對話框被打開時改變它的任何屬性,你可以定義這個方法贴铜。這個方法在每次打開對話框時被調(diào)用禁荸,而onCreateDialog(int) 僅在對話框第一次打開時被調(diào)用右蒲。如果你不定義onPrepareDialog(),那么這個對話框?qū)⒈3趾蜕洗未蜷_時一樣赶熟。這個方法也被傳遞以對話框的ID瑰妄,和在onCreateDialog()中創(chuàng)建的對話框?qū)ο蟆?個人理解是,在本Activity里第一次show某個Dialog映砖,則先調(diào)用onCreateDialog间坐,得到返回的Dialog對象并掛靠在Activity,保存Dialog對象的引用邑退,然后才顯示Dialog竹宋。這樣子,下次再show Dialog就不用重新創(chuàng)建Dialog對象地技,而是重用舊的)
定義onCreateDialog(int)和onPrepareDialog(int, Dialog)回調(diào)函數(shù)的最佳方法是使用一個switch 語句來檢查傳遞進(jìn)來的id 參數(shù)蜈七。每個case 應(yīng)該檢查一個唯一的對話框ID然后創(chuàng)建和定義相應(yīng)的對話框。比如莫矗,想象一下一個游戲使用兩個不同的對話框:一個用來指示這個游戲已經(jīng)暫停而另一個來指示游戲結(jié)束飒硅。首先,為每個對話框定義一個常量:
staticfinalintDIALOG_PAUSED_ID?=0;
staticfinalintDIALOG_GAMEOVER_ID?=1;
然后作谚,為每一個ID用一個switch case定義這個onCreateDialog(int) 回調(diào)函數(shù):
protectedDialog?onCreateDialog(intid)?{
Dialog?dialog;
switch(id)?{
caseDIALOG_PAUSED_ID:
//?do?the?work?to?define?the?pause?Dialog
break;
caseDIALOG_GAMEOVER_ID:
//?do?the?work?to?define?the?game?over?Dialog
break;
default:
dialog?=null;
}
returndialog;
}
當(dāng)是時候顯示其中之一的對話框時三娩,使用對話框ID調(diào)用showDialog(int):
showDialog(DIALOG_PAUSED_ID);
消除對話框Dismissing a Dialog
當(dāng)你準(zhǔn)備關(guān)閉對話框時,你可以通過對這個對話框調(diào)用dismiss()來消除它妹懒。如果需要雀监,你還可以從這個Activity中調(diào)用dismissDialog(int id)方法,這實際上將為你對這個對話框調(diào)用dismiss() 方法眨唬。
如果你想使用onCreateDialog(int id)方法來管理你對話框的狀態(tài)(就如同在前面的章節(jié)討論的那樣)会前,然后每次你的對話框消除的時候,這個對話框?qū)ο蟮臓顟B(tài)將由該Activity保留匾竿。如果你決定不再需要這個對象或者清除該狀態(tài)是重要的瓦宜,那么你應(yīng)該調(diào)用removeDialog(int id)。這將刪除任何內(nèi)部對象引用而且如果這個對話框正在顯示搂橙,它將被消除歉提。
使用消除偵聽器Using dismiss listeners
如果你希望你的應(yīng)用程序在一個對話框消亡的時候執(zhí)行一些流程笛坦,那么你應(yīng)該附著一個on-dismiss偵聽器到對話框上区转。
@Override
protectedvoidonPrepareDialog(intid,?Dialog?dialog)?{
switch(id){
casePROGRESS_DIALOG:
dialog.setOnDismissListener(newDialogInterface.OnDismissListener(){
@Override
publicvoidonDismiss(DialogInterface?dialog){
Toast.makeText(getApplicationContext(),
"dismiss?listener!",
Toast.LENGTH_SHORT)
.show();
}
});
}
}
然而, 請注意對話框也可以被“取消”。這是一個表明對話框被用戶顯示取消的特殊情況版扩。這將在用戶按“返回”按鈕時發(fā)生废离,或者這個對話框顯示的調(diào)用cancel()(也許通過對話框上的一個“取消”按鈕)。當(dāng)一個對話框被取消時礁芦,這個OnDismissListener 依然會被通知到蜻韭,但是如果你希望在對話框被顯示取消時被通知到(而不是通常的消除方式)悼尾,那么你應(yīng)該通過setOnCancelListener()注冊一個DialogInterface.OnCancelListener。
目前個人學(xué)習(xí)發(fā)現(xiàn)肖方,一般情況下闺魏,調(diào)用dialog.cancel()就會觸發(fā)onCancelLister。而點擊AlertDialog的NegativeButton (Cancel/No)是不會觸發(fā)的俯画。對于setOnCancelListener()要注意的是析桥,這里有兩個setOnCancelListener(),但返回值不同:
//AlertDialog.Builder調(diào)用的
publicAlertDialog.Builder?setOnCancelListener?(DialogInterface.OnCancelListener?onCancelListener)
//Dialog調(diào)用的
publicvoidsetOnCancelListener?(DialogInterface.OnCancelListener?listener)
警告對話框AlertDialog的使用
為了創(chuàng)建一個警告對話框艰垂,使用AlertDialog.Builder子類泡仗。通過AlertDialog.Builder(Context)獲取一個構(gòu)造器然后使用這個類的公共方法來定義警告對話框的所有屬性。當(dāng)?shù)玫綐?gòu)造器后猜憎,通過create().方法來獲取警告對話框?qū)ο竺湓酢S袝r我是不調(diào)用create()的,而是在設(shè)置好了后直接調(diào)用show()顯示AlertDialog胰柑。
增加按鈕Adding buttons
這就是我一開始很想知道的究竟如何添加Yes/No截亦,Ok/Cancel這樣的按鈕。原來是通過setPositiveButton(...)響應(yīng)Yes/Ok的點擊旦事,setNeutralButton(...)響應(yīng)中立行為的點擊魁巩,setNegativeButton(...)響應(yīng)No/Cancel的點擊。注意姐浮,只能各自設(shè)置一個按鈕來響應(yīng)點擊事件谷遂。
AlertDialog.Builder?builder?=newAlertDialog.Builder(this);
builder.setMessage("Are?you?sure?you?want?to?exit?")
.setCancelable(false)
.setPositiveButton("Yes",newDialogInterface.OnClickListener()?{
publicvoidonClick(DialogInterface?dialog,intid)?{
MyActivity.this.finish();
}
})
.setNegativeButton("No",newDialogInterface.OnClickListener()?{
publicvoidonClick(DialogInterface?dialog,intid)?{
dialog.cancel();
}
});
AlertDialog?alert?=?builder.create();
首先,為這個對話框添加一個消息setMessage(CharSequence)卖鲤。然后肾扰,開始函數(shù)鏈并設(shè)置該對話框為不能取消not cancelable (因此用戶不能使用返回按鈕關(guān)閉這個對話框)。對每個按鈕蛋逾,使用任一set...Button() 方法集晚,比如setPositiveButton(),該方法接受按鈕名稱以及一個定義用戶選中按鈕后所采取動作的DialogInterface.OnClickListener区匣。
增加一個列表Adding a list
finalCharSequence[]?items?=?{"Red","Green","Blue"};
AlertDialog.Builder?builder?=newAlertDialog.Builder(this);
builder.setTitle("Pick?a?color");
builder.setItems(items,newDialogInterface.OnClickListener()?{
publicvoidonClick(DialogInterface?dialog,intitem)?{
Toast.makeText(getApplicationContext(),?items[item],?Toast.LENGTH_SHORT).show();
}
});
AlertDialog?alert?=?builder.create();
首先偷拔,用setTitle(CharSequence)方法給對話框添加一個標(biāo)題。然后亏钩,添加用setItems()添加一個可選項列表莲绰,該列表接受一組顯示的items和一個DialogInterface.OnClickListener 來定義用戶選中按鈕后所采取動作。
增加復(fù)選框和單選按鈕
要在對話框里創(chuàng)建一個多選項列表(checkboxes)或者單選項(radio buttons)姑丑,可分別調(diào)用setMultiChoiceItems()和setSingleChoiceItems()方法蛤签。如果你在onCreateDialog()回調(diào)函數(shù)中創(chuàng)建這些可選列表,Android會幫你管理列表狀態(tài)栅哀。只要這個活動是激活的震肮,對話框會記住之前選中的items称龙,但如果用戶退出這個活動,用戶選擇將丟失戳晌。
注意: 為了在用戶離開或暫停這個活動的時候能夠保存選擇鲫尊,你必須通過活動生命期Activity Lifecycle來恰當(dāng)?shù)谋4婧突謴?fù)設(shè)置。為了永久保存選項沦偎,即使活動進(jìn)程被完全終止马昨,你需要使用數(shù)據(jù)存儲Data Storage技術(shù)。
finalCharSequence[]?items?=?{"Red","Green","Blue"};
AlertDialog.Builder?builder?=newAlertDialog.Builder(this);
builder.setTitle("Pick?a?color");
builder.setSingleChoiceItems(items,?-1,newDialogInterface.OnClickListener()?{
publicvoidonClick(DialogInterface?dialog,intitem)?{
Toast.makeText(getApplicationContext(),?items[item],?Toast.LENGTH_SHORT).show();
}
});
AlertDialog?alert?=?builder.create();
setSingleChoiceItems()的第二個參數(shù)是一個checkedItem整型數(shù)值扛施,指示了基于0的缺省選擇項的位置鸿捧。“-1”代表不會有默認(rèn)選擇項疙渣。
進(jìn)度對話框Progress Dialog的使用
ProgressDialog是AlertDialog類的一個擴(kuò)展匙奴,可以為一個未定義進(jìn)度的任務(wù)顯示一個旋轉(zhuǎn)輪形狀的進(jìn)度動畫,或者為一個指定進(jìn)度的任務(wù)顯示一個進(jìn)度條妄荔。
可以簡單地通過調(diào)用ProgressDialog.show()方法來顯示一個進(jìn)度對話框泼菌,而通過onCreateDialog(int)回調(diào)管理這個對話框是可選的,如下所示:
ProgressDialog.show(this,//?context
"",//?title
"Loading.?Please?wait...",//?message
true);//進(jìn)度是否是不確定的啦租,這只和創(chuàng)建進(jìn)度條有關(guān)
進(jìn)度對話框的缺省類型是一個旋轉(zhuǎn)輪哗伯,運行看到的是以下效果:
由于ProgressDialog是AlertDialog的擴(kuò)展類,所以ProgressDialog也能設(shè)置按鈕篷角,比如一個取消下載的按鈕焊刹。不過要注意的是,和前面的AlertDialog.Builder不同恳蹲,ProgressDialog是調(diào)用AlertDialog的setButton虐块,setButton2,setButton3函數(shù)嘉蕾,這些函數(shù)沒有明確哪個是正面/中立/負(fù)面的贺奠,由我們決定。
顯示進(jìn)度條Showing a progress bar
而選擇動畫進(jìn)度條顯示進(jìn)度:
1. ? 用類構(gòu)造器初始化進(jìn)度對話框错忱,ProgressDialog(Context)儡率。
2. ? 用setProgressStyle(int)方法設(shè)置進(jìn)度風(fēng)格為"STYLE_HORIZONTAL"以及設(shè)置其它屬性,比如消息以清。
創(chuàng)建ProgressDialog大概是這樣的:
ProgressDialog?progressDialog?=newProgressDialog(getApplicationContext());
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setIcon(R.drawable.alert_dialog_icon);
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(false);
3. ? 當(dāng)你準(zhǔn)備顯示這個對話框時儿普,調(diào)用show()或者從onCreateDialog(int)回調(diào)中返回ProgressDialog。
4. ? 你可以通過調(diào)用setProgress(int)設(shè)置當(dāng)前進(jìn)度百分比或者調(diào)用incrementProgressBy(int)方法增加進(jìn)度值玖媚。
官方文檔提供了如何在另一線程來跟蹤進(jìn)程進(jìn)度箕肃,讓進(jìn)度值變化婚脱。對此可以參考http://androidappdocs.appspot.com/guide/topics/ui/dialogs.html里面的代碼今魔。也可以查看后面的文章《有關(guān)Android線程的學(xué)習(xí)》里面的例子勺像,看看如何使用Handler, Message機(jī)制错森!
創(chuàng)建自定義對話框Creating a Custom Dialog
創(chuàng)建自定義對話框吟宦,首先要創(chuàng)建一個Layout xml 文件,在此不啰嗦了涩维。然后加載Layout有兩種方法殃姓,也是非常熟悉的那兩種方法:
1.?setContentView(int resources id)
2. 利用LayoutInflater加載
官方還提示我們,一般使用Dialog類來創(chuàng)建對話框瓦阐,是需要setTitle的蜗侈,不設(shè)置的話,標(biāo)題占用的空間保持為空睡蟋,但仍然可見踏幻。而不想要那個標(biāo)題,那應(yīng)該使用警告對話框AlertDialog來創(chuàng)建自定義對話框戳杀。然而该面,因為警告對話框可以很簡單的通過AlertDialog.Builder類來創(chuàng)建,你并不需要訪問上面使用的setContentView(int) 方法信卡。相反隔缀,你必須使用setView(View),則需要使用LayoutInflater來加載Layout得到View傍菇。
具體代碼參考http://androidappdocs.appspot.com/guide/topics/ui/dialogs.html