翻譯Dev Guide 之 創建Dialog

創建Dialog
一個Dialog通常是一個出現在目前Activity前方的小窗口。這個Dialog將接受用戶的交互而底下的Activity將會失去焦點。Dialog通常用於需要打擾用戶的通知,執行與應用程序進展直接相關的短暫任務(比如一個進度條或者登錄提示)。
Dialog類是創建Dialog的基礎類。但是,通常你不應該直接實例化Dialog類,而是使用以下子類之一:
 
  1.AlertDialog,可以管理0,1,2或者3個Button,和/或一個可以包含checkbox/radiobutton的可選項列表。AlertDialog可以構造大部分的DialogUI,並且是推薦的Dialog類型。
   2.ProgressDialog,展示了一個進度輪或者進度條,由於是AlertDialog的擴展,它也支持Button。
   3.DatePickerDialog,允許用戶選擇一個日期。
   4.TimePickerDialog,允許用戶選擇一個時間。
如果你希望定製自己的Dialog,你可以繼承Dialog類或者以上的任意子類,然後重新定義佈局。

顯示一個Dialog

一個Dialog總是作爲一個Activity的一部分來創建和顯示。通常你應該在你的Activity的onCreateDialog(int)回調函數內創建Dialog。當你使用這個回調的時候,Android系統自動管理每個Dialog的狀態並把它們掛到Activity,有效地讓它成爲每個Dialog的所有人。這樣,每個Dialog從Acitivity繼承了一些屬性。比如,當一個Dialog打開的時候,Menu鍵會打開爲這個Activity定義的optionsmenu,而Volume鍵會調整Activity使用的音頻流。
注意:如果你決定在onCreateDialog()外創建一個Dialog,那麼它對Acitivity不可見,但是你可以用setOwnerActivity(Activity)將它附着到Acitvity上。
當你想顯示一個Dialog時,調用showDialog(int)並傳遞進一個唯一標識你想顯示的Dialog的整數。
當一個Dialog第一次被請求時,Android從你的Activity調用onCreateDialog(int),在這個方法裏你應該實例化你的Dialog。傳入這個回調函數的ID跟傳入showDialog(int)的是同一個。創建好Dialog後,在函數的末尾返回此對象。
在顯示Dialog之前,Android還會調用可選的回調函數onPrepareDialog(int,Dialog)。如果你希望在每次打開Dialog的時候都修改它的屬性,那麼就定義這個函數。每次打開Dialog的時候這個函數會被調用,而onCreateDialog(int)只會在第一次打開Dialog的時候調用。如果你不定義onPrepareDialog(int,Dialog),那麼Dialog將會和它上次打開時一樣。Dialog的ID與你在onCreateDialog()裏創建的Dialog將一起被傳給這個函數。
調用showDialog(intid)時,會用id調用onCreateDialog(int)或者onPrepareDialog(int)進行創建或者修改,然後再顯示出來。
//定義onCreateDialog(int)和onPrepareDialog(int, Dialog)的最佳方式,是用一個switch聲明來檢查傳入的ID,每個case值檢查一個唯一的Dialog ID,然後創建和定義各自的Dialog。比如,想象一個遊戲使用了兩個Dialog:一個說明遊戲暫停,另一個說明遊戲結束。首先,爲每個Dialog定義一個整型ID:
    static final int DIALOG_PAUSED_ID = 0;
    static final int DIALOG_GAMEOVER_ID = 1;
//然後用一個包含了所有ID case的switch來定義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_PGAMEOVER_ID:
            // do the work to define the game over Dialog
            break;
        default:
            dialog = null;
        }
        return dialog;
    }
//要顯示dialog的時候,用dialog的id調用showDialog(int):
    showDialog(DIALOG_PAUSED_ID);


解散一個Dialog

當你準備關閉你的dialog的時候,你可以調用Dialog對象的的dismiss()方法來解散它。必要的話,也可以從Activity上調用dismissDialog(int),它會爲你有效地調用Dialog的dismiss()。
如果你用onCreateDialog(int)管理你的Dialog狀態(如上節討論),那麼每次你的Dialog被解散的時候,Activity會保存它的狀態。如果你決定你不再需要這個對象或者清理狀態很重要,那麼你需要調用removeDialog(int)。它會清除任何對此對象的內在關聯,如果此dialog正在顯示中的話,還會關閉它。
使用解散listener
如果你希望你的程序在解散Dialog的時候執行一些代碼,那麼你需要在你的dialog上附着on-dismisslistener。
首先定義DialogInterface.OnDismissListener接口。這個接口只有一個方法,onDismiss(DialogInterface),當dialog解散的時候會被調用。然後把你的OnDIsmissListener實現傳遞到setOnDismissListener()即可。
但是,注意Dialog也可以被cancel。這特指用戶明確cancel這個dialog的情況。當用戶按下back鍵來關閉dialog,或者Dialog顯示調用cancel()(也許從dialog上的cancel按鈕)時會發生。當一個dialog被cancel的時候,會通知OnDismissListener,但是如果你希望被告知dialog是顯示調用cancel()而不是普通的dismiss,那麼你需要註冊一個DialogInterface.onCancelListener或者setOncancelListener()。


創建一個AlertDialog

AlertDialog是Dialog類的擴展,可以構造大部分的DialogUI,並且是推薦的Dialog類型。當dialog用到以下特性之一時你就應使用AlertDialg:
 
   一個title。
   一個文本消息。
   一個,兩個或者三個Button。
   一個可選列表(包括可選的checkbox和radiobut)。
注意在AlertDialog文本消息和列表不能同時顯示。
爲了創建一個AlertDialog,使用AlertDialog.Builder子類。用AlertDialog.Builder(Context)獲得一個Builder,然後使用這個類的公共方法定義AlertDialog的所有屬性。完成後就可通過create()取回AlertDialog對象。
接下來的內容展示瞭如何用AlertDialog.Builder類來定義AlertDialog的各種屬性。

添加Button

爲了創建有side-by-side的Button的AlertDialog,使用set...Button()函數:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage("Are you sure you want to exit?")
                 .setCancelable(false)
                 .setPositiveButton("Yse", new DialogInterface.OnClickListener() {
                   
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        MyActivity.finish();
                       
                    }
                })
                .setNegativeButton("no", new DialogInterface.OnClickListener() {
                   
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                       
                    }
                });
        AlertDialog alert = builder.create();
首先用setMessage(CharSequence)爲dialog添加一個message,然後開始函數鏈,用setCancelable(boolean)設置了dialog不能被cancel(用戶不能用back鍵關閉dialog),爲每個Button用一個set...Button(),接受Button的名字和DialogInterface.OnClickListener。
注意:每種Button只能添加一個,總共有三種爲positive,neutral和negative。


添加一個列表

創建可選列表要用setItems()函數:
final CharSequence[] items = {"Red","Green","Blue"};
       
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Pick a color");
        builder.setItems(items, new DialogInterface.OnClickListener() {
           
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(getApplicationContext(), items[which], Toast.LENGTH_SHORT).show();
            }
        });
        AlertDialog alert = builder.create();
首先,用setTitle(CharSequence)給Dialog設置一個標題,然後用setItem()添加一個可選列表,它接收一個選項數組用於顯示和一個DialogInterface.OnClickListener用於監聽點擊選項。


添加checkbox和radiobutton

向Dialog裏添加一個有複選選項checkbox或者單選選項radiobutton的列表,各自要用setMultiChoiceItems()和setSingleChoiceItems()函數。如果你在onCreateDialog()回調函數裏使用了這些,Android會替你管理列表的狀態。只要Activity還活躍,dialog就會記住上次選擇的選項,但是如果用戶退出Activity,選擇就忘記了。
注意:爲了在用戶離開或者暫停Activity時保存選擇,你必須在整個Activity生命週期中進行恰當的存儲和恢復。爲了永久地保存選擇,即使Activity的進程完全停止,你需要使用一種數據存儲技術(DataStorage)。
要創建一個選項可單選列表,代碼和上面一樣,只需要把setItems()換成setSingleChoiceItems()。
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() {
           
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(getApplicationContext(), items[which], Toast.LENGTH_SHORT).show();
            }
        });
        AlertDialog alert = builder.create();
setSingleChoiceItems()中第二個參數是標記選項的一個整數,說明了這個零基列表默認的選項位置,選擇“-1”表示默認無選項被選中。


創建ProgressDialog

ProgressDialog是Dialog的擴展,可以爲一個有未定義進度的任務以一個旋轉的輪子形式顯示進度動畫,或者爲一個有已定義進度的任務顯示進度條,還可以提供按鈕用於比如退出一個下載。
打開一個ProgressDialog只要調用ProgressDialog.show()就可以了。比如:
    ProgressDialog dialog = ProgressDialog.show(MyActivity.this, "", "Loading, Please wait...", true);
第一個參數是應用程序的context,第二個是dialog的標題,第三個是message,第四個表示進度是否不定(只跟進度條有關,下節討論)。
默認的ProgressDialog類型就是旋轉的輪子,如果你想要創建按粒度顯示進度的進度條,需要更多代碼如下。

顯示進度條



用動態進度條顯示進度的步驟:
   1.用類構造器ProgressDialog(Context)初始化ProgessDialog。
   2.用setProgressStyle(int)把進度類型設置爲“STYLE_HORIZONTAL”,並設置其他屬性,如message等。
   3.當你準備顯示Dialog時,調用show(),或者返回來自onCreateDialog(int)回調的ProgressDialog。
   4.你可以用目前完成的百分比調用setProgress(int),或者用加到目前完成百分比的增量值調用incrementProgressBy(int),來增加顯示在進度條上的進度量。
注意設置進度一定要在show()之後,否則設置無效。
比如你的設置可以是這樣:
ProgressDialog progressDialog = new ProgressDialog(mContext);
    progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    progressDialog.setMessage("Loading...");
    progressDialog.setCancelable(false);

設置很簡單。創建一個ProgressDialog的大部分代碼實際上都包含在更新程序中了。你也許會發現有必要在應用程序中創建一個次線程去完成這個工作,然後有一個Handler對象把進度回報給Activity的UI線程。


創建自定義Dialog

如果你想自主設計一個Dialog,你可以用layout和widget元素爲Dialog窗口創建一個你自己的佈局。定義完佈局之後,把根View對象或者佈局資源ID傳給setContentView(View)。步驟:
   1.創建XML佈局文件,如custom_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

                
      android:id="@+id/layout_root"

                 
      android:orientation="horizontal"

                 
      android:layout_width="fill_parent"

                      
android:layout_height="fill_parent"

                      
android:padding="10dp"

                      >
        
        
<ImageView android:id="@+id/image"

                      android:layout_width="wrap_content"

                 
      android:layout_height="fill_parent"

                 
      android:layout_marginRight="10dp"

                />

               <TextView android:id="@+id/text"

                      
android:layout_width="wrap_content"

                    
  android:layout_height="fill_parent"

                      
 android:textColor="#FFF"

               />
        
</LinearLayout>

這個XML在一個LinearLayout裏定義了一個ImageView和一個TextView。

    2.把上面的佈局設置爲dialog的內容佈局,定義ImageView和TextView的內容。

Context mContext = getApplicationContext();
        
Dialog dialog = new Dialog(mContext);


        
dialog.setContentView(R.layout.custom_dialog);
        
dialog.setTitle("Custom Dialog");


        
TextView text = (TextView) dialog.findViewById(R.id.text);
        
text.setText("Hello, this is a custom dialog!");
        
ImageView image = (ImageView) dialog.findViewById(R.id.image);
        
image.setImageResource(R.drawable.android);

在你實例化Dialog後,將layout資源ID傳給setContentView(int)把你自己的layout設爲dialog的內容視圖,然後Dialog有了一個已定義的佈局,可以用findViewById(int)來捕捉View對象並修改其內容了。

注意,經過測試發現,按如上代碼直接對自定義Dialog使用findViewById()是不能獲取控件的,正確的做法是:
    先獲取LayoutInflater,用其inflate(int, ViewGroup)方法對自定義佈局進行縮放,得到一個View。
    然後用自己的Dialog的setContentView(View)將這個View設置爲Dialog的佈局。
    在通過這個View的對象名來調用findViewById()來獲取控件。 但是設置佈局文件和設置其控件並無嚴格的順序,爲了便於記憶和理解,儘量先設置佈局文件,在設置其控件。     3.搞定。現在你可以顯示你的Dialog了。 一個用Dialog基礎類做的Dialog必須有個標題。如果你不調用setTitle(),那標題位置就是空的,但仍然可見。如果你根本不想要標題,那麼你應該用AlertDialog類創建自己的Dialog。但是,由於AlertDialog用AlertDialog.Builder創建是最簡單的,你接觸不到上面用的setContentView(View),而必須用setView(View)。這個函數接受一個View對象,所以你需要膨脹佈局XML的根View對象。 要膨脹XML佈局,用getLayoutInflater()或者getSystemService()獲取LayoutInflater,然後調用inflate(int, ViewGroup),第一個參數是佈局資源ID,第二個是根View的ID。然後你就可以被膨脹的layout去發現View對象及設置它們的屬性了。然後實例化AlertDialog.Builder,並用setView()把被膨脹了的layout設置到Dialog中。 下面有個在AlertDialog中創建自定義Dialog的示例:
AlertDialog.Builder builder;

        AlertDialog alertDialog;

        

        Context mContext = getApplicationContext();

        LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(LAYOUT_INFLATER_SERVICE);

        View layout = inflater.inflate(R.id.custom_dialog, 

                        (ViewGroup)layout.findViewById(R.id.layout_root));

        

        TextView text = (TextView)findViewById(R.id.text);

//同樣的,這裏獲取TextView應該用(TextView)layout.findViewById(R.id.text);

        text.setText("Hello, this is a custom dialog!");

        ImageView image = (ImageView)findViewById(R.id.image);

        image.setImageResource(R.drawable.android);

        

        builder = new AlertDialog.Builder(mContext);

        builder.setView(layout);

        alertDialog = builder.create();

爲你的佈局使用AlertDialog可以利用AlertDialog的內在特性,比如被管理的按鈕,可選列表,標題,圖標等等。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章