顯示對話框
?? ?對話框經常作為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)?
警告對話框AlertDialog的使用
?? ?為了創建一個警告對話框,使用 AlertDialog.Builder 子類。通過 AlertDialog.Builder(Context) 獲取一個構造器然后使用這個類的公共方法來定義警告對話框的所有屬性。當得到構造器后,通過 create() .方法來獲取警告對話框對象。有時我是不調用create()的,而是在設置好了后直接調用 show() 顯示AlertDialog。
增加按鈕Adding buttons
?? ?這就是我一開始很想知道的究竟如何添加Yes/No,Ok/Cancel這樣的按鈕。原來是通過 setPositiveButton(...) 響應Yes/Ok的點擊, setNeutralButton(...) 響應中立行為的點擊, setNegativeButton(...) 響應No/Cancel的點擊。注意,只能各自設置一個按鈕來響應點擊事件。
- 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();?
?? ?首先,為這個對話框添加一個消息 setMessage(CharSequence) 。然后,開始函數鏈并設置該對話框為不能取消not cancelable ( 因此用戶不能使用返回按鈕關閉這個對話框 )。對每個按鈕,使用任一set...Button() 方法,比如setPositiveButton(),該方法接受按鈕名稱以及一個定義用戶選中按鈕后所采取動作的 DialogInterface.OnClickListener 。
增加一個列表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) 方法給對話框添加一個標題。然后,添加用 setItems() 添加一個可選項列表,該列表接受一組顯示的items和一個DialogInterface.OnClickListener 來定義用戶選中按鈕后所采取動作。
增加復選框和單選按鈕
?? ?要在對話框里創建一個多選項列表(checkboxes)或者單選項(radio buttons),可分別調用 setMultiChoiceItems() 和 setSingleChoiceItems() 方法。如果你在onCreateDialog()回調函數中創建這些可選列表,Android會幫你管理列表狀態。只要這個活動是激活的,對話框會記住之前選中的items,但如果用戶退出這個活動,用戶選擇將丟失。
?? ? 注意: 為了在用戶離開或暫停這個活動的時候能夠保存選擇,你必須通過活動生命期Activity Lifecycle來恰當的保存和恢復設置。為了永久保存選項,即使活動進程被完全終止,你需要使用數據存儲Data Storage技術。
- 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() 的第二個參數是一個checkedItem整型數值,指示了基于0的缺省選擇項的位置。“-1”代表不會有默認選擇項。
進度對話框Progress Dialog的使用
?? ? ProgressDialog 是 AlertDialog 類的一個擴展,可以為一個未定義進度的任務顯示一個旋轉輪形狀的進度動畫,或者為一個指定進度的任務顯示一個進度條。
?? ?可以簡單地通過調用ProgressDialog.show()方法來顯示一個進度對話框,而通過onCreateDialog(int)回調管理這個對話框是可選的,如下所示:
- ProgressDialog.show( this ,? //?context ?
- ???? "" ,? //?title ?
- ???? "Loading.?Please?wait..." ,? //?message ?
- ???? true );? //進度是否是不確定的,這只和創建進度條有關 ?
進度對話框的缺省類型是一個旋轉輪,運行看到的是以下效果:
?? ?由于ProgressDialog是AlertDialog的擴展類,所以ProgressDialog也能設置按鈕,比如一個取消下載的按鈕。不過要注意的是,和前面的AlertDialog.Builder不同,ProgressDialog是調用 AlertDialog 的 setButton , setButton2 , setButton3 函數,這些函數沒有明確哪個是正面/中立/負面的,由我們決定。
顯示進度條Showing a progress bar
而選擇動畫進度條顯示進度:
1. ? 用類構造器初始化進度對話框,ProgressDialog(Context)。
2. ? 用setProgressStyle(int)方法設置進度風格為"STYLE_HORIZONTAL"以及設置其它屬性,比如消息。
創建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. ? 當你準備顯示這個對話框時,調用show()或者從onCreateDialog(int)回調中返回ProgressDialog。
4. ? 你可以通過調用setProgress(int)設置當前進度百分比或者調用incrementProgressBy(int)方法增加進度值。
官方文檔提供了如何在另一線程來跟蹤進程進度,讓進度值變化。對此可以參考 http://androidappdocs.appspot.com/guide/topics/ui/dialogs.html 里面的代碼。也可以查看后面的文章《 有關Android線程的學習 》里面的例子,看看如何使用Handler, Message機制!
創建自定義對話框Creating a Custom Dialog
?? ?創建自定義對話框,首先要創建一個Layout xml 文件,在此不啰嗦了。然后加載Layout有兩種方法,也是非常熟悉的那兩種方法:
?? ?1.?setContentView(int resources id)
?? ?2. 利用LayoutInflater加載
?? 官方還提示我們,一般使用Dialog類來創建對話框,是需要setTitle的,不設置的話,標題占用的空間保持為空,但仍然可見。而不想要那個標題,那應該使用警告對話框AlertDialog來創建自定義對話框。然而,因為警告對話框可以很簡單的通過 AlertDialog.Builder 類來創建,你并不需要訪問上面使用的setContentView(int) 方法。相反,你必須使用setView(View),則需要使用LayoutInflater來加載Layout得到View。
?????
常用控件的使用:
進度條:
@Override public void onClick(View v) { //設定Handler對象,主要是處理新開線程完畢后交給主線程來處理的數據 mhandler = new Handler(){ @Override public void handleMessage(Message msg) { String name =(String)msg.obj; Toast.makeText(ProgressDialogActivity.this, name + "把師傅救出來了", 1).show(); } }; //創建ProgressDialog對象 Dialog = new ProgressDialog(this); //設定ProgressDialog的樣式為進度條 Dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); //設定ProgressDialog的最大值為100,這里就是100只小妖怪啦 Dialog.setMax(100); //設定ProgressDialog不能取消,你不能半途而廢啊,當然要100只打完啦 Dialog.setCancelable(false); String name = null; switch (v.getId()) { case R.id.wukong: //設定名字,看是誰在打妖怪啊 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() { //打完妖怪的數量 int count = 0; public void run() { try { //打完妖怪小于100只的時候運行的方法 while(count <= 100){ Dialog.setProgress(count++); //睡眠0.2秒,你也得讓他們休息一下啊,呵呵 Thread.sleep(200); } Dialog.cancel(); //給handler發送消息,看是誰在打妖怪,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); // 創建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); // 取得兩個控件中的值 String user_str = user.getText().toString(); String pass_str = pass.getText().toString(); // 驗證賬號和密碼 validate(user_str, pass_str); } }); builder.setNegativeButton("取消", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); // 這個很重要的,是dialog的顯示功能,如果這個沒有的話,是不會顯示出來的 builder.show(); }
?
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
