顯示對話框
?? ?對話框經(jīng)常作為Activity的一部分來創(chuàng)建和顯示。你通常應(yīng)該從 protected Dialog?Activity.onCreateDialog (int id) 回調(diào)方法里創(chuàng)建對話框。當(dāng)你使用這個(gè)回調(diào)函數(shù)時(shí),Android系統(tǒng)會(huì)有效的設(shè)置這個(gè)Activity為每個(gè)對話框的所有者,從而 自動(dòng)管理每個(gè)對話框的狀態(tài)并掛靠到Activity上。這樣,每個(gè)對話框繼承這個(gè)Activity的特定屬性。比如,當(dāng)一個(gè)對話框打開時(shí),菜單鍵顯示為這個(gè)Activity定義的選項(xiàng)菜單,音量鍵修改Activity使用的音頻流 。
-
注意:?如果你決定在
onCreateDialog
()方法之外創(chuàng)建一個(gè)對話框,它將不會(huì)被附著到活動(dòng)上。不過,你可以通過
setOwnerActivity(Activity)
把它附著到一個(gè)活動(dòng)上。?
?? ?當(dāng)你想要顯示一個(gè)對話框時(shí),調(diào)用 showDialog(int id) 方法并傳遞一個(gè)唯一標(biāo)識(shí)這個(gè)對話框的整數(shù)。
?? ?當(dāng)對話框第一次被請求時(shí),Android從你的Activity中調(diào)用 onCreateDialog(int id) ,你應(yīng)該在這里初始化這個(gè)對話框Dialog。這個(gè)回調(diào)方法被傳以和 showDialog(int id) 相同的ID。當(dāng)你創(chuàng)建這個(gè)對話框后,在Activity的最后返回這個(gè)對象。
?? ?在對話框被顯示之前,Android還調(diào)用了可選的回調(diào)函數(shù) onPrepareDialog(int id, Dialog) . 如果你 想在每一次對話框被打開時(shí)改變它的任何屬性,你可以定義這個(gè)方法 。這個(gè)方法 在每次打開對話框時(shí)被調(diào)用 ,而 onCreateDialog(int) 僅在對話框第一次打開時(shí)被調(diào)用 。 如果你不定義onPrepareDialog(),那么這個(gè)對話框?qū)⒈3趾蜕洗未蜷_時(shí)一樣 。這個(gè)方法也被傳遞以對話框的ID,和在onCreateDialog()中創(chuàng)建的對話框?qū)ο蟆? 個(gè)人理解是,在本Activity里第一次show某個(gè)Dialog,則先調(diào)用onCreateDialog,得到返回的Dialog對象并掛靠在Activity,保存Dialog對象的引用,然后才顯示Dialog。這樣子,下次再show Dialog就不用重新創(chuàng)建Dialog對象,而是重用舊的 )
?? ?定義 onCreateDialog(int) 和 onPrepareDialog(int, Dialog) 回調(diào)函數(shù)的最佳方法是使用一個(gè)switch 語句來檢查傳遞進(jìn)來的id 參數(shù)。每個(gè)case 應(yīng)該檢查一個(gè)唯一的對話框ID然后創(chuàng)建和定義相應(yīng)的對話框。比如,想象一下一個(gè)游戲使用兩個(gè)不同的對話框:一個(gè)用來指示這個(gè)游戲已經(jīng)暫停而另一個(gè)來指示游戲結(jié)束。首先,為每個(gè)對話框定義一個(gè)常量:
-
static
?
final
?
int
?DIALOG_PAUSED_ID?=?
0
;?
-
static
?
final
?
int
?DIALOG_GAMEOVER_ID?=?
1
;?
然后,為每一個(gè)ID用一個(gè)switch case定義這個(gè)onCreateDialog(int) 回調(diào)函數(shù):
-
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;?
-
}?
當(dāng)是時(shí)候顯示其中之一的對話框時(shí),使用對話框ID調(diào)用showDialog(int):
-
showDialog(DIALOG_PAUSED_ID);?
消除對話框Dismissing a Dialog
?? ?當(dāng)你準(zhǔn)備關(guān)閉對話框時(shí),你可以通過對這個(gè)對話框調(diào)用 dismiss( ) 來消除它。如果需要,你還可以從這個(gè)Activity中調(diào)用 dismissDialog(int id) 方法,這實(shí)際上將為你對這個(gè)對話框調(diào)用dismiss() 方法。
?? ?如果你想使用 onCreateDialog(int id) 方法來管理你對話框的狀態(tài)(就如同在前面的章節(jié)討論的那樣),然后每次你的對話框消除的時(shí)候,這個(gè)對話框?qū)ο蟮臓顟B(tài)將由該Activity保留。如果你決定不再需要這個(gè)對象或者清除該狀態(tài)是重要的,那么你應(yīng)該調(diào)用 removeDialog(int id) 。這將刪除任何內(nèi)部對象引用而且如果這個(gè)對話框正在顯示,它將被消除。
使用消除偵聽器Using dismiss listeners
?? ?如果你希望你的應(yīng)用程序在一個(gè)對話框消亡的時(shí)候執(zhí)行一些流程,那么你應(yīng)該附著一個(gè)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();?
-
????????????}?
-
????????});?
-
????}?
-
}?
?? ?然而, 請注意對話框也可以被“取消”。這是一個(gè)表明對話框被用戶顯示取消的特殊情況。這將在用戶按“返回”按鈕時(shí)發(fā)生,或者這個(gè)對話框顯示的調(diào)用 cancel() (也許通過對話框上的一個(gè)“取消”按鈕)。當(dāng)一個(gè)對話框被取消時(shí),這個(gè)OnDismissListener 依然會(huì)被通知到,但是如果你希望在對話框被顯示取消時(shí)被通知到(而不是通常的消除方式),那么你應(yīng)該通過 setOnCancelListener() 注冊一個(gè) DialogInterface.OnCancelListener 。
?? ?目前個(gè)人學(xué)習(xí)發(fā)現(xiàn),一般情況下,調(diào)用dialog.cancel()就會(huì)觸發(fā)onCancelLister。而點(diǎn)擊AlertDialog的NegativeButton (Cancel/No)是不會(huì)觸發(fā)的。對于 setOnCancelListener() 要注意的是,這里有兩個(gè)setOnCancelListener(),但返回值不同:
-
//AlertDialog.Builder調(diào)用的
?
-
public
?AlertDialog.Builder?setOnCancelListener?(DialogInterface.OnCancelListener?onCancelListener)?
-
?
-
//Dialog調(diào)用的
?
-
public
?
void
?setOnCancelListener?(DialogInterface.OnCancelListener?listener)?
警告對話框AlertDialog的使用
?? ?為了創(chuàng)建一個(gè)警告對話框,使用 AlertDialog.Builder 子類。通過 AlertDialog.Builder(Context) 獲取一個(gè)構(gòu)造器然后使用這個(gè)類的公共方法來定義警告對話框的所有屬性。當(dāng)?shù)玫綐?gòu)造器后,通過 create() .方法來獲取警告對話框?qū)ο蟆S袝r(shí)我是不調(diào)用create()的,而是在設(shè)置好了后直接調(diào)用 show() 顯示AlertDialog。
增加按鈕Adding buttons
?? ?這就是我一開始很想知道的究竟如何添加Yes/No,Ok/Cancel這樣的按鈕。原來是通過 setPositiveButton(...) 響應(yīng)Yes/Ok的點(diǎn)擊, setNeutralButton(...) 響應(yīng)中立行為的點(diǎn)擊, setNegativeButton(...) 響應(yīng)No/Cancel的點(diǎn)擊。注意,只能各自設(shè)置一個(gè)按鈕來響應(yīng)點(diǎn)擊事件。
-
AlertDialog.Builder?builder?=?
new
?AlertDialog.Builder(
this
);?
-
builder.setMessage(
"Are?you?sure?you?want?to?exit?"
)?
-
???????.setCancelable(
false
)?
-
???????.
setPositiveButton
(
"Yes"
,?
new
?DialogInterface.OnClickListener()?{?
-
???????????
public
?
void
?onClick(DialogInterface?dialog,?
int
?id)?{?
-
????????????????MyActivity.
this
.finish();?
-
???????????}?
-
???????})?
-
???????.
setNegativeButton
(
"No"
,?
new
?DialogInterface.OnClickListener()?{?
-
???????????
public
?
void
?onClick(DialogInterface?dialog,?
int
?id)?{?
-
????????????????dialog.cancel();?
-
???????????}?
-
???????});?
-
AlertDialog?alert?=?builder.create();?
?? ?首先,為這個(gè)對話框添加一個(gè)消息 setMessage(CharSequence) 。然后,開始函數(shù)鏈并設(shè)置該對話框?yàn)椴荒苋∠鹡ot cancelable ( 因此用戶不能使用返回按鈕關(guān)閉這個(gè)對話框 )。對每個(gè)按鈕,使用任一set...Button() 方法,比如setPositiveButton(),該方法接受按鈕名稱以及一個(gè)定義用戶選中按鈕后所采取動(dòng)作的 DialogInterface.OnClickListener 。
增加一個(gè)列表Adding a list
-
final
?CharSequence[]?items?=?{
"Red"
,?
"Green"
,?
"Blue"
};?
-
??
-
AlertDialog.Builder?builder?=?
new
?AlertDialog.Builder(
this
);?
-
builder.setTitle(
"Pick?a?color"
);?
-
builder.
setItems
(items,?
new
?DialogInterface.OnClickListener()?{?
-
????
public
?
void
?onClick(DialogInterface?dialog,?
int
?item)?{?
-
????????Toast.makeText(getApplicationContext(),?items[item],?Toast.LENGTH_SHORT).show();?
-
????}?
-
});?
-
AlertDialog?alert?=?builder.create();?
?? ?首先,用 setTitle(CharSequence) 方法給對話框添加一個(gè)標(biāo)題。然后,添加用 setItems() 添加一個(gè)可選項(xiàng)列表,該列表接受一組顯示的items和一個(gè)DialogInterface.OnClickListener 來定義用戶選中按鈕后所采取動(dòng)作。
增加復(fù)選框和單選按鈕
?? ?要在對話框里創(chuàng)建一個(gè)多選項(xiàng)列表(checkboxes)或者單選項(xiàng)(radio buttons),可分別調(diào)用 setMultiChoiceItems() 和 setSingleChoiceItems() 方法。如果你在onCreateDialog()回調(diào)函數(shù)中創(chuàng)建這些可選列表,Android會(huì)幫你管理列表狀態(tài)。只要這個(gè)活動(dòng)是激活的,對話框會(huì)記住之前選中的items,但如果用戶退出這個(gè)活動(dòng),用戶選擇將丟失。
?? ? 注意: 為了在用戶離開或暫停這個(gè)活動(dòng)的時(shí)候能夠保存選擇,你必須通過活動(dòng)生命期Activity Lifecycle來恰當(dāng)?shù)谋4婧突謴?fù)設(shè)置。為了永久保存選項(xiàng),即使活動(dòng)進(jìn)程被完全終止,你需要使用數(shù)據(jù)存儲(chǔ)Data Storage技術(shù)。
-
final
?CharSequence[]?items?=?{
"Red"
,?
"Green"
,?
"Blue"
};?
-
??
-
AlertDialog.Builder?builder?=?
new
?AlertDialog.Builder(
this
);?
-
builder.setTitle(
"Pick?a?color"
);?
-
builder.
setSingleChoiceItems
(items,?-
1
,?
new
?DialogInterface.OnClickListener()?{?
-
????
public
?
void
?onClick(DialogInterface?dialog,?
int
?item)?{?
-
????????Toast.makeText(getApplicationContext(),?items[item],?Toast.LENGTH_SHORT).show();?
-
????}?
-
});?
-
AlertDialog?alert?=?builder.create();?
?? ? setSingleChoiceItems() 的第二個(gè)參數(shù)是一個(gè)checkedItem整型數(shù)值,指示了基于0的缺省選擇項(xiàng)的位置。“-1”代表不會(huì)有默認(rèn)選擇項(xiàng)。
進(jìn)度對話框Progress Dialog的使用
?? ? ProgressDialog 是 AlertDialog 類的一個(gè)擴(kuò)展,可以為一個(gè)未定義進(jìn)度的任務(wù)顯示一個(gè)旋轉(zhuǎn)輪形狀的進(jìn)度動(dòng)畫,或者為一個(gè)指定進(jìn)度的任務(wù)顯示一個(gè)進(jìn)度條。
?? ?可以簡單地通過調(diào)用ProgressDialog.show()方法來顯示一個(gè)進(jìn)度對話框,而通過onCreateDialog(int)回調(diào)管理這個(gè)對話框是可選的,如下所示:
-
ProgressDialog.show(
this
,?
//?context
?
-
????
""
,?
//?title
?
-
????
"Loading.?Please?wait..."
,?
//?message
?
-
????
true
);?
//進(jìn)度是否是不確定的,這只和創(chuàng)建進(jìn)度條有關(guān)
?
進(jìn)度對話框的缺省類型是一個(gè)旋轉(zhuǎn)輪,運(yùn)行看到的是以下效果:
?? ?由于ProgressDialog是AlertDialog的擴(kuò)展類,所以ProgressDialog也能設(shè)置按鈕,比如一個(gè)取消下載的按鈕。不過要注意的是,和前面的AlertDialog.Builder不同,ProgressDialog是調(diào)用 AlertDialog 的 setButton , setButton2 , setButton3 函數(shù),這些函數(shù)沒有明確哪個(gè)是正面/中立/負(fù)面的,由我們決定。
顯示進(jìn)度條Showing a progress bar
而選擇動(dòng)畫進(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?=?
new
?ProgressDialog(getApplicationContext());??
-
??
-
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);??
-
progressDialog.setIcon(R.drawable.alert_dialog_icon);??
-
progressDialog.setMessage(
"Loading..."
);??
-
progressDialog.setCancelable(
false
);??
3. ? 當(dāng)你準(zhǔn)備顯示這個(gè)對話框時(shí),調(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)建自定義對話框,首先要?jiǎng)?chuàng)建一個(gè)Layout xml 文件,在此不啰嗦了。然后加載Layout有兩種方法,也是非常熟悉的那兩種方法:
?? ?1.?setContentView(int resources id)
?? ?2. 利用LayoutInflater加載
?? 官方還提示我們,一般使用Dialog類來創(chuàng)建對話框,是需要setTitle的,不設(shè)置的話,標(biāo)題占用的空間保持為空,但仍然可見。而不想要那個(gè)標(biāo)題,那應(yīng)該使用警告對話框AlertDialog來創(chuàng)建自定義對話框。然而,因?yàn)榫鎸υ捒蚩梢院芎唵蔚耐ㄟ^ AlertDialog.Builder 類來創(chuàng)建,你并不需要訪問上面使用的setContentView(int) 方法。相反,你必須使用setView(View),則需要使用LayoutInflater來加載Layout得到View。
?????
常用控件的使用:
進(jìn)度條:
@Override
public void onClick(View v)
{
//設(shè)定Handler對象,主要是處理新開線程完畢后交給主線程來處理的數(shù)據(jù)
mhandler = new Handler(){
@Override
public void handleMessage(Message msg)
{
String name =(String)msg.obj;
Toast.makeText(ProgressDialogActivity.this, name + "把師傅救出來了", 1).show();
}
};
//創(chuàng)建ProgressDialog對象
Dialog = new ProgressDialog(this);
//設(shè)定ProgressDialog的樣式為進(jìn)度條
Dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
//設(shè)定ProgressDialog的最大值為100,這里就是100只小妖怪啦
Dialog.setMax(100);
//設(shè)定ProgressDialog不能取消,你不能半途而廢啊,當(dāng)然要100只打完啦
Dialog.setCancelable(false);
String name = null;
switch (v.getId())
{
case R.id.wukong:
//設(shè)定名字,看是誰在打妖怪啊
name = "孫悟空";
Dialog.setTitle(name);
//圖片
Dialog.setIcon(R.drawable.wukong);
//消息
Dialog.setMessage("悟空在打妖怪");
//自定義打斗的方法
doFlight(name);
break;
case R.id.bajie:
//同上
name = "豬八戒";
Dialog.setTitle(name);
Dialog.setIcon(R.drawable.bajie);
Dialog.setMessage("八戒在打妖怪");
doFlight(name);
break;
case R.id.shaseng:
//同上
name = "沙和尚";
Dialog.setTitle(name);
Dialog.setIcon(R.drawable.shaseng);
Dialog.setMessage("沙僧在打妖怪");
doFlight(name);
break;
}
}
private void doFlight(final String name)
{
//顯示ProgressDialog
Dialog.show();
//新開一條線程
new Thread()
{
//打完妖怪的數(shù)量
int count = 0;
public void run()
{
try
{
//打完妖怪小于100只的時(shí)候運(yùn)行的方法
while(count <= 100){
Dialog.setProgress(count++);
//睡眠0.2秒,你也得讓他們休息一下啊,呵呵
Thread.sleep(200);
}
Dialog.cancel();
//給handler發(fā)送消息,看是誰在打妖怪,handler是主線程中的
Message message = new Message();
message.obj = name;
mhandler.sendMessage(message);
} catch (InterruptedException e)
{
Dialog.cancel();
}
};
}.start();
}
?
?
?
對話框的使用:
?
/**
* 登錄框
*/
protected void dialog_show()
{
// 將Layout中的login.xml匹配給視圖控件
LayoutInflater inflater = LayoutInflater.from(this);
final View view = inflater.inflate(R.layout.login, null);
// 創(chuàng)建Dialog
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("登錄框");
builder.setView(view);
builder.setPositiveButton("登錄", new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
// 取得login.xml中的賬號EditText和密碼EditText控件
EditText user = (EditText) view.findViewById(R.id.user);
EditText pass = (EditText) view.findViewById(R.id.pass);
// 取得兩個(gè)控件中的值
String user_str = user.getText().toString();
String pass_str = pass.getText().toString();
// 驗(yàn)證賬號和密碼
validate(user_str, pass_str);
}
});
builder.setNegativeButton("取消", new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
});
// 這個(gè)很重要的,是dialog的顯示功能,如果這個(gè)沒有的話,是不會(huì)顯示出來的
builder.show();
}
?
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

