Android UI- 對話框 (AlertDialog & ProgressDialog)

轉(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末猾瘸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子丢习,更是在濱河造成了極大的恐慌须妻,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泛领,死亡現(xiàn)場離奇詭異荒吏,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)渊鞋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門绰更,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人锡宋,你說我怎么就攤上這事儡湾。” “怎么了执俩?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵徐钠,是天一觀的道長。 經(jīng)常有香客問我役首,道長尝丐,這世上最難降的妖魔是什么显拜? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮爹袁,結(jié)果婚禮上远荠,老公的妹妹穿的比我還像新娘。我一直安慰自己失息,他們只是感情好譬淳,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著盹兢,像睡著了一般邻梆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上绎秒,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天确虱,我揣著相機(jī)與錄音,去河邊找鬼替裆。 笑死校辩,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的辆童。 我是一名探鬼主播宜咒,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼把鉴!你這毒婦竟也來了故黑?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤庭砍,失蹤者是張志新(化名)和其女友劉穎场晶,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體怠缸,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡诗轻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了揭北。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扳炬。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖搔体,靈堂內(nèi)的尸體忽然破棺而出恨樟,到底是詐尸還是另有隱情,我是刑警寧澤疚俱,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布劝术,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏养晋。R本人自食惡果不足惜衬吆,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望匙握。 院中可真熱鬧,春花似錦陈轿、人聲如沸圈纺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛾娶。三九已至,卻和暖如春潜秋,著一層夾襖步出監(jiān)牢的瞬間蛔琅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工峻呛, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留罗售,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓钩述,卻偏偏與公主長得像寨躁,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子牙勘,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容