日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

《Android Dev Guide》系列教程12:用戶界面之建立對(duì)話框Dialogs

 lifei_szdz 2012-12-26

《Android Dev Guide》系列教程12:用戶界面之建立對(duì)話框Dialogs

分類: Android Application 1877人閱讀 評(píng)論(1) 收藏 舉報(bào)

《Android Dev Guide》系列教程12:用戶界面之建立對(duì)話框Dialogs

懶骨頭(http://blog./iamlazybone

 

建立對(duì)話框Dialog

Dialog是一個(gè)常見(jiàn)的顯示在當(dāng)前activity之上的小窗口。下面的activity會(huì)失去焦點(diǎn),而dialog回接受用戶輸入。dialog常用在與程序直接相關(guān)聯(lián)的通知和短小的activity中。

Android API支持以下幾種dialog:

AlertDialog:

它可以包含0、1、2、3個(gè)按鈕,或者一個(gè)列表或者多選單選按鈕等,它是一個(gè)功能最強(qiáng)大的dialog接口,詳細(xì)信息可參考下面的章節(jié)。

ProgressDialog:

它會(huì)顯示一個(gè)進(jìn)度條或者進(jìn)度環(huán),因?yàn)樗茿lertDialog的子類,所有野支持按鈕。

DatePickerDialog:

用來(lái)選擇日期的對(duì)話框。

TimerPickerDialog:

用來(lái)選擇時(shí)間的。

如果你想要定制自己的dialog,你可以繼承Dialog對(duì)象,或者它的任何一個(gè)子類,并且定義一個(gè)新的布局。


顯示一個(gè)Dialog

Dialog 總是被當(dāng)做activity的一部分來(lái)創(chuàng)建和顯示。你可以在activity的onCreateDialog(int)方法中創(chuàng)建一個(gè)dialog。當(dāng)你使用這個(gè)方法,android系統(tǒng)會(huì)自動(dòng)的管理每個(gè)dialog的狀態(tài)并且關(guān)聯(lián)到所在的activity中,讓這個(gè)activity成為dialog的管理者。每個(gè)dialog都會(huì)繼承activity的某些特性。例如,當(dāng)dialog打開(kāi)時(shí),按下menu彈出的是所在activity的菜單,調(diào)節(jié)的是所在activity的音量。

注意:如果你決定在onCreateDialog()方法之外建立dialog,他將不會(huì)連接到activity中,此時(shí),你可以使用setOwnerActivity(Activity)方法來(lái)綁定activity。

當(dāng)你顯示dialog時(shí),調(diào)用showDialog(int)來(lái)傳遞一個(gè)dialog的id句柄。

當(dāng)一個(gè)dialog首次顯示時(shí),android會(huì)在實(shí)例化dialog的activity中調(diào)用onCreateDialog(int)方法?;卣{(diào)方法會(huì)傳遞相同的id給showDialog(int)。當(dāng) 創(chuàng)建完一個(gè)dialog后,會(huì)再方法的最后返回這個(gè)對(duì)象。

在dialog顯示前,android回調(diào)用可選的方法 :onPrepareDialog(int,Dialog)。如果你想在每次調(diào)用dialog時(shí)改變一些配置的話,你可以定義這個(gè)方法。OnPrepareDialog(int,Dialog)方法會(huì)在每次調(diào)用dialog時(shí)調(diào)用,而onCreateDialog(int)方法只會(huì)調(diào)用一次。如果你不定義onPrepareDialog()方法,那么打開(kāi)的dialog會(huì)保持上一次的狀態(tài)。這個(gè)方法也會(huì)傳遞dialog的id句柄。

定義這兩個(gè)onXXX()方法最好使用一個(gè)switch結(jié)構(gòu)來(lái)檢測(cè)Id參數(shù),每一個(gè)case項(xiàng)都應(yīng)該創(chuàng)建自己的dialog。例如。想象一個(gè)游戲使用兩個(gè)不同的dialog,一個(gè)暫停一個(gè)結(jié)束游戲:

  1. static final int DIALOG_PAUSED_ID = 0;  
  2. static final int DIALOG_GAMEOVER_ID = 1;  
 

然后,再onCreateDialog(int)里根據(jù)id創(chuàng)建dialog:

  1. protected Dialog onCreateDialog(int id) {  
  2.     Dialog dialog;  
  3.     switch(id) {  
  4.     case DIALOG_PAUSED_ID:  
  5.         // do the work to define the pause Dialog  
  6.         break;  
  7.     case DIALOG_GAMEOVER_ID:  
  8.         // do the work to define the game over Dialog  
  9.         break;  
  10.     default:  
  11.         dialog = null;  
  12.     }  
  13.     return dialog;  
  14. }  
 

注意:在例子中沒(méi)有詳寫,因?yàn)槎xdialog屬于另外的章節(jié)。

現(xiàn)在可以調(diào)用showDilaog(int)來(lái)顯示一個(gè)dialog了:

  1. showDialog(DIALOG_PAUSED_ID);  
 


取消Dialog的顯示

調(diào)用dialog的dismiss()方法可以隱藏正在顯示的dialog,如果必要的話,可以調(diào)用activity的dismissDialog(int)方法,他倆效果是一樣的。如果使用的onCreateDialog(int)方法來(lái)管理dialog的狀態(tài),那么每次當(dāng)你的dialog消失時(shí),對(duì)話框的狀態(tài)都會(huì)被activity保存著。如果不太需要這個(gè)對(duì)話框或者不希望activity保留dialog的狀態(tài),可以調(diào)用removeDialog(int)方法。它會(huì)刪除任何關(guān)于dialog的引用,如果dialog正在顯示,此方法會(huì)讓dialog隱藏。

隱藏dialog監(jiān)聽(tīng)器的使用

如果你想讓activity在dialog隱藏時(shí)執(zhí)行某些動(dòng)作,那么你可以建立一個(gè)監(jiān)聽(tīng)器。

首先定義DialogInterface.OnDismissListerner 接口,這個(gè)接口只有一個(gè)方法,onDismiss(DialogInterface),當(dāng)dialog隱藏時(shí)被調(diào)用,然后傳遞OnDismissListener 對(duì)象給setOnDismissLister()方法。

然而,注意dialog也可以是取消,用戶讓這個(gè)dialog取消也是一種特殊的情況。當(dāng)用戶按下back鍵時(shí),或者調(diào)用cancel()方法時(shí)會(huì)發(fā)生這種情況。當(dāng)一個(gè)dialog被取消時(shí),OnDismissLister監(jiān)聽(tīng)器仍然會(huì)收到通知,但如果你喜歡的到明確的取消消息,可以注冊(cè)DialogInterface.OnCancelLister監(jiān)聽(tīng)器。


AlertDialog的創(chuàng)建

AlertDialog時(shí)Dialog的子類,Dilaog絕大多數(shù)是這個(gè)強(qiáng)大類型,你可以在以下情況下使用:

@ 一個(gè)標(biāo)題

@ 一個(gè)文本信息

@ 一個(gè)兩個(gè)或者三個(gè)按鈕

@ 一個(gè)單選或者多選列表

建立AlertDialog,使用AlertDialog.Builder子類。使用AlertDialog.Builder(Context)方法來(lái)獲得一個(gè)Builder,并且使用它的公共方法來(lái)定義AlertDialog所有的屬性。最后,調(diào)用create()方法來(lái)顯示。

下面顯示了如何定義AlertDialog.Builder類的一些屬性,如果在onCreateDialog()方法中使用了例子中的代碼,你可以返回結(jié)果對(duì)話框來(lái)顯示這個(gè)dialog。

添加按鈕

創(chuàng)建一個(gè)上圖所示包含按鈕的AlertDialog,可以使用setXXXButton()方法:

  1. AlertDialog.Builder builder = new AlertDialog.Builder(this);  
  2. builder.setMessage("Are you sure you want to exit?")  
  3.        .setCancelable(false)  
  4.        .setPositiveButton("Yes"new DialogInterface.OnClickListener() {  
  5.            public void onClick(DialogInterface dialog, int id) {  
  6.                 MyActivity.this.finish();  
  7.            }  
  8.        })  
  9.        .setNegativeButton("No"new DialogInterface.OnClickListener() {  
  10.            public void onClick(DialogInterface dialog, int id) {  
  11.                 dialog.cancel();  
  12.            }  
  13.        });  
  14. AlertDialog alert = builder.create();  
 

首先,通過(guò)setMessage(CharSequence)為dialog添加一個(gè)message,然后通過(guò)setCancelable(boolean)方法讓此dialog無(wú)法通過(guò)按back鍵來(lái)取消。每個(gè)按鈕都需要調(diào)用setXXXButton()方法,例如setPositiveButton()方法,DialogInterface.OnClickListener()類會(huì)定義按下按鈕所要做的處理。

注意:每種類型的按鈕只能加一個(gè),這就是說(shuō),你不能添加多于一個(gè)的positive按鈕。最多能添加三個(gè)按鈕,positive, neutral, 和 negative.他們名字所顯示的功能并未實(shí)現(xiàn),但能幫你記住要實(shí)現(xiàn)的功能。

添加一個(gè)列表

如上圖所示,使用setItems()方法添加可選列表:

  1. final CharSequence[] items = {"Red""Green""Blue"};  
  2. AlertDialog.Builder builder = new AlertDialog.Builder(this);  
  3. builder.setTitle("Pick a color");  
  4. builder.setItems(items, new DialogInterface.OnClickListener() {  
  5.     public void onClick(DialogInterface dialog, int item) {  
  6.         Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();  
  7.     }  
  8. });  
  9. AlertDialog alert = builder.create();  
 

首先,使用setTitle(CharSequence)方法設(shè)置標(biāo)題,然后使用setItem()方法添加可選列表,這個(gè)列表會(huì)接收一個(gè)item數(shù)組來(lái)顯示,DialogInterFace.OnClickListener類會(huì)定義他們的點(diǎn)擊事件。

添加選擇框和單選按鈕

通過(guò)setMultiChoiceItems()方法或 setSingleChoiceItems()方法來(lái)分別建立一個(gè)多選按鈕列表或者單選列表,如果再onCreateDialog()方法中建立了其中一種列表,android會(huì)為你管理這個(gè)list。當(dāng)activity處于活動(dòng)狀態(tài)時(shí),dialog會(huì)記住當(dāng)才選中項(xiàng),如果退出了程序,選擇結(jié)果便會(huì)丟失。

注意:當(dāng)用戶離開(kāi)或者暫停activity時(shí),如果你想保存選擇狀態(tài),你必須在整個(gè)activity的生命周期中保存這個(gè)設(shè)置。永久的保存所選項(xiàng),甚至當(dāng)前進(jìn)程完全被關(guān)閉,你需要使用數(shù)據(jù)存儲(chǔ)方式來(lái)保存。建立一個(gè)如上圖所示的列表dialog,代碼和上面的例子相同,只需要把setItems()方法改為setSingleChoiceItems()方法即可。

  1. final CharSequence[] items = {"Red""Green""Blue"};  
  2. AlertDialog.Builder builder = new AlertDialog.Builder(this);  
  3. builder.setTitle("Pick a color");  
  4. builder.setSingleChoiceItems(items, -1new DialogInterface.OnClickListener() {  
  5.     public void onClick(DialogInterface dialog, int item) {  
  6.         Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();  
  7.     }  
  8. });  
  9. AlertDialog alert = builder.create();  
 

setSingleChoiseItems()方法的第二個(gè)參數(shù)是checkedItem的id值,從0開(kāi)始對(duì)應(yīng)著位置,如果返回”-1“表明沒(méi)有選中任何項(xiàng)。

 


進(jìn)度對(duì)話框 ProgressDialog 的建立

ProgressDialog時(shí)AlertDialog的子類,它會(huì)顯示一個(gè)表示進(jìn)度的圓形動(dòng)畫(huà),來(lái)表示一個(gè)進(jìn)度或者任務(wù)正在運(yùn)行,也可以時(shí)一個(gè)進(jìn)度條,能清晰的表示出進(jìn)度。他也能添加按鈕,比如取消一個(gè)下載進(jìn)程。

調(diào)用ProgressDialog.show()方法可以顯示進(jìn)程對(duì)話框,例如,上圖的對(duì)話框可通過(guò)如下代碼生成:

  1. ProgressDialog dialog = ProgressDialog.show(MyActivity.this"",   
  2.                         "Loading. Please wait..."true);  
 

第一個(gè)參數(shù)是程序的Context引用,四二個(gè)為標(biāo)題,第三個(gè)為顯示的信息,最后一個(gè)為類型,(當(dāng)創(chuàng)建進(jìn)度條時(shí)才會(huì)用到,下節(jié)討論)。

默認(rèn)的進(jìn)度條為圓形的樣式,如果你想生成一個(gè)通過(guò)具體數(shù)值來(lái)顯示任務(wù)的加載情況的進(jìn)度條,下一節(jié)會(huì)討論。

進(jìn)度條的顯示

顯示一個(gè)進(jìn)度條要經(jīng)過(guò)以下幾個(gè)步驟:

1-使用ProgressDialog(Context)方法初始化

2-使用setProgressStyle(int)方法設(shè)置類型。

3-調(diào)用show()方法顯示,或者在onCreateDialog(int)方法里返回一個(gè)ProgressDialog。

4-你可以調(diào)用setProgress(int)方法,根據(jù)整體的任務(wù)完成度來(lái)設(shè)置一個(gè)具體進(jìn)度值,或者使用incrementPressBy(int)來(lái)設(shè)置一個(gè)增長(zhǎng)值。

例如:

  1. ProgressDialog progressDialog;  
  2. progressDialog = new ProgressDialog(mContext);  
  3. progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);  
  4. progressDialog.setMessage("Loading...");  
  5. progressDialog.setCancelable(false);  
 

設(shè)置代碼非常簡(jiǎn)單,大部分代碼是在dialog參與進(jìn)程并且更新的功能里。你會(huì)發(fā)現(xiàn),另起一個(gè)線程來(lái)做這個(gè)工作是很有必要的,要把消息傳遞給activity的UI線程里需要用到 Handler 消息機(jī)制。如果你并不熟悉使用額外的線程,那么看這個(gè)例子:

這個(gè)例子使用了第二個(gè)線程來(lái)跟蹤任務(wù)的進(jìn)度(實(shí)際上只是在數(shù)值上加到100),線程通過(guò) Handler 發(fā)了一個(gè)Message 給主activity,然后主activity更新ProgressDialog。

  1. package com.example.progressdialog;  
  2. import android.app.Activity;  
  3. import android.app.Dialog;  
  4. import android.app.ProgressDialog;  
  5. import android.os.Bundle;  
  6. import android.os.Handler;  
  7. import android.os.Message;  
  8. import android.view.View;  
  9. import android.view.View.OnClickListener;  
  10. import android.widget.Button;  
  11. public class NotificationTest extends Activity {  
  12.     static final int PROGRESS_DIALOG = 0;  
  13.     Button button;  
  14.     ProgressThread progressThread;  
  15.     ProgressDialog progressDialog;  
  16.      
  17.     /** Called when the activity is first created. */  
  18.     public void onCreate(Bundle savedInstanceState) {  
  19.         super.onCreate(savedInstanceState);  
  20.         setContentView(R.layout.main);  
  21.         // Setup the button that starts the progress dialog  
  22.         button = (Button) findViewById(R.id.progressDialog);  
  23.         button.setOnClickListener(new OnClickListener(){  
  24.             public void onClick(View v) {  
  25.                 showDialog(PROGRESS_DIALOG);  
  26.             }  
  27.         });   
  28.     }  
  29.      
  30.     protected Dialog onCreateDialog(int id) {  
  31.         switch(id) {  
  32.         case PROGRESS_DIALOG:  
  33.             progressDialog = new ProgressDialog(NotificationTest.this);  
  34.             progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);  
  35.             progressDialog.setMessage("Loading...");  
  36.             progressThread = new ProgressThread(handler);  
  37.             progressThread.start();  
  38.             return progressDialog;  
  39.         default:  
  40.             return null;  
  41.         }  
  42.     }  
  43.     // Define the Handler that receives messages from the thread and update the progress  
  44.     final Handler handler = new Handler() {  
  45.         public void handleMessage(Message msg) {  
  46.             int total = msg.getData().getInt("total");  
  47.             progressDialog.setProgress(total);  
  48.             if (total >= 100){  
  49.                 dismissDialog(PROGRESS_DIALOG);  
  50.                 progressThread.setState(ProgressThread.STATE_DONE);  
  51.             }  
  52.         }  
  53.     };  
  54.     /** Nested class that performs progress calculations (counting) */  
  55.     private class ProgressThread extends Thread {  
  56.         Handler mHandler;  
  57.         final static int STATE_DONE = 0;  
  58.         final static int STATE_RUNNING = 1;  
  59.         int mState;  
  60.         int total;  
  61.          
  62.         ProgressThread(Handler h) {  
  63.             mHandler = h;  
  64.         }  
  65.          
  66.         public void run() {  
  67.             mState = STATE_RUNNING;     
  68.             total = 0;  
  69.             while (mState == STATE_RUNNING) {  
  70.                 try {  
  71.                     Thread.sleep(100);  
  72.                 } catch (InterruptedException e) {  
  73.                     Log.e("ERROR""Thread Interrupted");  
  74.                 }  
  75.                 Message msg = mHandler.obtainMessage();  
  76.                 Bundle b = new Bundle();  
  77.                 b.putInt("total", total);  
  78.                 msg.setData(b);  
  79.                 mHandler.sendMessage(msg);  
  80.                 total++;  
  81.             }  
  82.         }  
  83.           
  84.         /* sets the current state for the thread, 
  85.          * used to stop the thread */  
  86.         public void setState(int state) {  
  87.             mState = state;  
  88.         }  
  89.     }  
  90. }  
 

 


自定義dialog的建立

如果你想自定義dialog的布局,你可以自己創(chuàng)建一個(gè)dialog布局。定義好之后,傳遞根View對(duì)象或者資源ID到setContextView(View)方法。

例如,如上圖的dialog:

1-建立一個(gè)xml布局文件custom_dialog.xml;

  1. <LinearLayout xmlns:android="http://schemas./apk/res/android"  
  2.               android:id="@+id/layout_root"  
  3.               android:orientation="horizontal"  
  4.               android:layout_width="fill_parent"  
  5.               android:layout_height="fill_parent"  
  6.               android:padding="10dp"  
  7.               >  
  8.     <ImageView android:id="@+id/image"  
  9.                android:layout_width="wrap_content"  
  10.                android:layout_height="fill_parent"  
  11.                android:layout_marginRight="10dp"  
  12.                />  
  13.     <TextView android:id="@+id/text"  
  14.               android:layout_width="wrap_content"  
  15.               android:layout_height="fill_parent"  
  16.               android:textColor="#FFF"  
  17.               />  
  18. </LinearLayout>  
 

這個(gè)xml在LinearLayout里定義了一個(gè)ImageView和TextView。

2-設(shè)置上面的布局為dialog的context view ,并且定義ImageView和TextView兩個(gè)元素。

  1. Context mContext = getApplicationContext();  
  2. Dialog dialog = new Dialog(mContext);  
  3. dialog.setContentView(R.layout.custom_dialog);  
  4. dialog.setTitle("Custom Dialog");  
  5. TextView text = (TextView) dialog.findViewById(R.id.text);  
  6. text.setText("Hello, this is a custom dialog!");  
  7. ImageView image = (ImageView) dialog.findViewById(R.id.image);  
  8. image.setImageResource(R.drawable.android);  
 

實(shí)例化dialog后,使用setContextView(int)方法設(shè)置自定義的布局。現(xiàn)在dialog便有了一個(gè)自定義的布局,你可以使用findViewById(int)方法來(lái)獲得或者修改布局。

3-完成了,現(xiàn)在你可以顯示自定義的dialog了。

一個(gè)dialog必須有一個(gè)title,如果你沒(méi)有調(diào)用setTitile()方法,那么會(huì)標(biāo)題處會(huì)顯示空,但dialog仍然可見(jiàn),如果你不想顯示標(biāo)題,只有寫一個(gè)自己的dialog類了。然而,因?yàn)橐粋€(gè)AlertDialog使用AlertDialog.builder類創(chuàng)建起來(lái)非常簡(jiǎn)單,你不必使用setContextView(int)方法。但必須使用setView(view)方法代替。這個(gè)方法會(huì)接受一個(gè)view參數(shù),你需要從xml中得到根view元素。

得到xml布局,通過(guò)LayoutInflater類的getLayoutflater()方法(或者getSystemService()方法),然后調(diào)用inflate(int,ViewGroup)方法,第一個(gè)參數(shù)是xml文件id,第二個(gè)參數(shù)是根view的id,在這點(diǎn)上,你可以使用inflated 布局來(lái)獲得xml中的view對(duì)象并且定義ImageView和TextView對(duì)象,然后實(shí)例化AlertDialog.Builder類并且使用setView(View)方法來(lái)設(shè)置布局。

這有一個(gè)自定義dialog布局文件的例子:

  1. AlertDialog.Builder builder;  
  2. AlertDialog alertDialog;  
  3. Context mContext = getApplicationContext();  
  4. LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);  
  5. View layout = inflater.inflate(R.layout.custom_dialog,  
  6.                                (ViewGroup) findViewById(R.id.layout_root));  
  7. TextView text = (TextView) layout.findViewById(R.id.text);  
  8. text.setText("Hello, this is a custom dialog!");  
  9. ImageView image = (ImageView) layout.findViewById(R.id.image);  
  10. image.setImageResource(R.drawable.android);  
  11. builder = new AlertDialog.Builder(mContext);  
  12. builder.setView(layout);  
  13. alertDialog = builder.create();  
 

使用自定義布局這種方式來(lái)生成dialog,可以讓你使用更高級(jí)的特性,比如管理按鈕、列表、標(biāo)題、圖標(biāo)等。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多