【翻譯文檔】Android Dialog

來源:互聯網
上載者:User

聲明:本文翻譯自Android SDK內建文檔中的guide/topics/ui/dialogs.html

 

一個dialog通常是指出現在當前Activity前面的小視窗,當dialog出現後,被它部分遮蓋的Activity將失去焦點,一切的使用者操作交由這個dialog處理。

Android API支援以下類型的Dialog對象:

AlertDialog -- 允許你在其上添加0、1、2或3個button,而且它還可以包含一個提供了可選項(如checkboxes或radio buttons等)的列表。正確的使用AlertDialog可以構建大多數Dialog介面。

ProgressDialog -- 用於顯示一個progress wheel或者一個progress bar。ProgressDialog是一個別擴充了的AlertDialog,所以它自然也允許你在其上添加button。

DatePickerDialog -- 允許使用者選擇時間的dialog。

TimePickerDialog -- 允許使用者選擇時間的dialog。

如何顯示一個Dialog

一個dialog常常作為一個Activity的一部分被建立和顯示。你應該在你建立的Activity的 onCreateDialog(int)這個回呼函數中建立dialog。當你使用這個回呼函數,Android系統就會自動管理每個dialog的狀態並且建立每個dialog和對應Activity之間的串連,使對應的Activity成為對應dialog的“owner”。這樣,每個dialog就從Activity繼承了某些屬性。例如,當一個dialog處於open狀態時,使用者按下Menu鍵就會顯示你為這個Activity定義的menu。

注意:如果你決定在onCreateDialog()外面建立一個dialog,Android系統不會把它“粘貼” 到某個Activity上。如果需要,你可以使用setOwnerActivity(Activity)方法將一個dialog“粘貼”到一個 Activity上。

當你想要顯示一個dialog時,請調用showDialog(int)方法,並且傳遞給它一個能唯一標識你想要顯示的dialog的整數。

當一個dialog第一次被請求的時候,Android系統會呼叫你的Activity中的 onCreateDialog(int)方法,你要在這個方法體裡執行個體化一個Dialog。onCreateDialog和showDialog一樣,都需要你傳遞給它們一個dialog ID。在你建立完一個Dialog對象後,請讓onCreateDialog方法返回一個Dialog對象的引用。

在dialog被顯示之前,Android也會呼叫onPrepareDialog(int, Dialog)。這個方法是可選的,如果你想在每次開啟dialog時改變它任何樹形,你就需要定義這個方法。每次dialog別開啟時,Android 都會呼叫onPrepareDialog(int, Dialog),而只有當dialog是被第一次開啟時才呼叫onCreateDialog(int)。如果你比重寫

onPrepareDialog(int, Dialog),dialog就會呈現使用者上一次開啟它時的狀態。這個方法也需要你傳遞給它一個dialog的ID,同時還需要你傳遞給它一個你使用 onCreateDialog()方法建立並返回的Dialog對象的引用。

最好的定義 onCreateDialog(int)和onPrepareDialog(int, Dialog) 這兩個回呼函數的方法是使用switch語句檢測被傳入的id實參。每個case應該檢測一個惟一的dialog ID,然後建立和定義各自的Dialog對象。例如,假設需要兩個不同對話方塊的一個遊戲程式,一個對話方塊指示這個遊戲已被暫停,兩一個指示遊戲結束。

首先,為每個dialog定義一個ID:

view plaincopy to clipboardprint?

static final int DIALOG_PAUSE_ID = 0;

static final int DIALOG_GAMEOVER_ID = 1;

static final int DIALOG_PAUSE_ID = 0;

static final int DIALOG_GAMEOVER_ID = 1;

然後,定義onCreateDialog(int)方法,其中應該包含用於區別不同dialog ID的switch語句:

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;}

注意:在以上例子中,在case分支語句中並沒有代碼,因為本節還沒有講述定義Dialog的處理過程。

接下來,是時候去顯示一個dialog了,請調用showDialog(int),並傳遞給它一個dialog的ID。

showDialog(DIALOG_PAUSED_ID);

showDialog(DIALOG_PAUSED_ID);

如何讓一個Dialog消失

當你打算關閉一個dialog,可以調用Dialog對象成員方法dismiss()方法來打發它。如果有必要,你可以從為你呼叫dismiss()的Activity中調用dismisDialog(int)。

如果你正在使用onCreateDialog(int)去管理dialog的狀態,那每次你的dialog消失後,Activity就持有Dialog對象的狀態資訊。如果你真的不再需要這個Dialog對象,或者你真的需要清除這個狀態,那你應該呼叫 removeDialog(int)。這個方法會擦除所有與這個對象相關的內部引用,並且如果dialog正在被顯示,這個方法會dismiss這個 dialog。

如何使用dismiss監聽器

如果你想讓你的應用程式在dialog消失的過程中做一些事,你就應該為你的Dialog綁定一個on-dismiss監聽器。

首先,定義DialogInterface.OnDismissListener介面。這個介面只有一個方法—— onDismiss(DialogInterface),在dialog消失後,系統就會呼叫這個方法。然後把你的實現了 OnDismissListener介面的對象傳遞給setOnDismissListener()。

然後,值得注意的是dialog也能夠夠取消(be cancelled)。這是一種標識dialog被使用者顯示取消的特殊情況。當使用者按下了返回鍵或者關閉了這個dialog或者應用程式員顯示的調用了 cannel()時(可能在dialog中的“Cancel”按鈕被按下的處理方法中調用的),就會發生這種情況。當一個dialog處在被取消的狀態,OnDismissListener也會接收到來自Android的通知,但如果你想Android在這個dialog被顯示取消(and not dismissed normally),就得使用setOnCancelListener()方法註冊一個
DialogInterface.OnCancelListener。

如何建立一個AlertDialog

AlertDialog是Dialog類的擴充類,它可以構建很多中dialog使用者介面,Android也建議應用程式員使用AlertDialog完成dialog使用者介面的構建。你可以用它構建具有任何一下屬性的dialog:

A title

A text message

One, two, or three buttons

A list of selectable items(with optional checkboxes or radio buttons)

為了建立一個AlertDialog,你需要使用AlertDialog.Builder子類。使用 AlertDialog.Builder(Context)獲得一個Builder,然後使用類的公開方法去定義AlertDialog的所有屬性。在你已經完成了對Builder的操作後,呼叫create()方法取回這個AlertDialog對象。

以下內容論述和展示了如何使用AlertDialog.Builder類,定義AlertDialog的各種屬性。如果你在onCreateDialog()回呼函數中使用下面任何一段代碼,你就可以返回你想要顯示的具有某些屬性的目標Dialog對象。

添加button

如果你想構建一個帶有button的dialog,需要調用set...Button()方法。

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)為dialog添加一條提示訊息。然後,開始 method-chaining並且呼叫setCancelable(boolean)函數設定這個dialog為不可取消(使用者就不能通過按返回鍵關閉這個dialog)。使用set...Button()方法添加button,例如,使用接收在button上顯示的字串和對使用者按下按鈕動作進行處理的DialogInterface.OnClickListener這兩個參數的setPositiveButton()方法為dialog添加一個按鈕。

注意:不可以在一個dialog上同時添加兩個“positive” button。最多可以在一個dialog上添加三個button:positive, neutral, and negative button。

添加列表:

使用setItems()方法為AlertDialog添加一個可供使用者選擇的列表。

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)為dialog添加一個title。然後,調用 setItems()為dialog添加一個list,這個list接收一組items以顯示,並且 DialogInterface.OnClickListener對使用者的不同選擇進行處理。

添加checkboxes和radio buttons

為了建立帶有multiple-choice items(checkboxes)或single-choice items(radio buttons)的dialog,需要分別使用setMultiChoiceItems()和setSingleChoiceItems()方法。如果你是在onCreateDialog建立這些可選list,Android就會為你管理這個list的狀態。只要這個Activity是active的,這個dialog就會記住之前被使用者選中的items,但當使用者離開當前Activity,the
selection 就會丟失。

注意:為了在使用者離開或者暫停Activity時儲存selection,在整個Activity的生命週期中,你一定要在的適當的時候sava和restore

the setting。如果想要永久儲存the selections,就需要使用資料存放區技術儲存這些setting.

要建立一個帶有single-choice items的AlertDialog,可以使用建立帶有lists的AlertDialog的程式碼片段,但是,需要用setSingleChoiceItems()代替setItems()。

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()的第二個參數是一個整數值,指示預設預設選中哪個list(zero-based),使用“-1”指示預設情況下不應該選中任何item。

 

建立ProgressDialog

一個ProcessDialog是一個擴充了的AlertDialog類,一個執行個體化了ProcessDialog的dialog能夠顯示一個一個進度條,同時也能夠提供buttons,例如取消下載的button。

只要呼叫ProgressDialog.show()就可以開啟一個progress dialog。

ProgressDialog dialog = ProgressDialog.show(MyActivity.this, "",

"Loading. Please wait...", true);

第一個參數是該應用程式的Context,第二個參數是這個dialog的title(留白),第三個參數是顯示在dialog上的字串,最後一個參數標識這個progress是否是indeterminate(這隻和進度條的建立相關,我們將在一下節中討論)。

進度dialog的預設方格是將進度顯示為一個圓環。如果你要建立一個可以顯示下載進程的進度條,請閱讀一下內容。

顯示進度條

要想顯示帶有動態進度資訊的進度條,你需要:

1. 調用ProgressDialog(Context)這個建構函式初始化ProgressDialog。

2. 調用setProgressStyle(int)將進度條的風格設定為STYLE_HORIZONTAL。當然,你也可以給這個dialog設定其它屬性,例如在它上面顯示一條訊息。

3. 當你準備好去顯示一個dialog了,可以調用show()方法,或者從onCreateDialog(int)這個回調方法中返回ProgressDialog。

4. 你可以調用並傳遞一個目前總完成百分比的整數值給setProgress(int),或者調用並傳遞一個你想要加到目前已完成百分比的整數值給incrementProgressBy(int)。

例如,你可能像這樣建立ProgressDialog。

ProgressDialog progressDialog;progressDialog = new ProgressDialog(mContext);progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);progressDialog.setMessage("Loading...");progressDialog.setCancelable(false);

大多數建立progress dialog的代碼都會同時建立一個用於更新這個progress dialog的線程。為了完成更新progress dialog的任務,你需要在你的應用程式中再開啟一個線程,然後使用Handler對象向Activity的UI線程傳遞進度資訊。如果你還沒有熟練使用帶有Handler的新加線程,請看下面的新啟一個線程更新progress dialog的例子。

包含新啟線程的ProgressDialog

這個例子使用一個新啟動的線程跟蹤進度(實際上只是將數值累加到100)資訊,每當有了新的進度,這個新啟的線程就使用Handler向主Activity發送一條Message,然後主Acitvity就會更新ProgressDialog。

package org.vhow.android.ui.dialogs;import android.app.Activity;import android.app.Dialog;import android.app.ProgressDialog;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class Dialogs extends Activity{static final int PROGRESS_DIALOG = 0;Button button;ProgressThread progressThread;ProgressDialog progressDialog;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);// setup the button that starts the progress dialogbutton = (Button) findViewById(R.id.progressDialog);button.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v){showDialog(PROGRESS_DIALOG);}});}@Overrideprotected Dialog onCreateDialog(int id){switch (id){case PROGRESS_DIALOG:progressDialog = new ProgressDialog(Dialogs.this);progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);progressDialog.setMessage("Loading...");progressThread = new ProgressThread(handler);progressThread.start();return progressDialog;default:return null;}}// Define the Handler that receives messages from the thread and update the// progressfinal Handler handler = new Handler(){public void handleMessage(Message msg){int total = msg.getData().getInt("total");progressDialog.setProgress(total);if (total >= 100){dismissDialog(PROGRESS_DIALOG);progressThread.setState(ProgressThread.STATE_DONE);}}};/*** Nested class that performs progress calculations(counting)*/private class ProgressThread extends Thread{Handler mHandler;final static int STATE_DONE = 0;final static int STATE_RUNNING = 1;int mState;int total;ProgressThread(Handler h){mHandler = h;}public void run(){mState = STATE_RUNNING;total = 0;while (mState == STATE_RUNNING){try{Thread.sleep(100);}catch (InterruptedException e){Log.e("ERROR", "Thread Interrupted");}Message msg = mHandler.obtainMessage();Bundle b = new Bundle();b.putInt("total", total);msg.setData(b);mHandler.sendMessage(msg);total++;}}/*** sets the current state for the thread, used to stop teh thread*/public void setState(int state){mState = state;}}}package org.vhow.android.ui.dialogs;import android.app.Activity;import android.app.Dialog;import android.app.ProgressDialog;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class Dialogs extends Activity{static final int PROGRESS_DIALOG = 0;Button button;ProgressThread progressThread;ProgressDialog progressDialog;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);// setup the button that starts the progress dialogbutton = (Button) findViewById(R.id.progressDialog);button.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v){showDialog(PROGRESS_DIALOG);}});}@Overrideprotected Dialog onCreateDialog(int id){switch (id){case PROGRESS_DIALOG:progressDialog = new ProgressDialog(Dialogs.this);progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);progressDialog.setMessage("Loading...");progressThread = new ProgressThread(handler);progressThread.start();return progressDialog;default:return null;}}// Define the Handler that receives messages from the thread and update the// progressfinal Handler handler = new Handler(){public void handleMessage(Message msg){int total = msg.getData().getInt("total");progressDialog.setProgress(total);if (total >= 100){dismissDialog(PROGRESS_DIALOG);progressThread.setState(ProgressThread.STATE_DONE);}}};/*** Nested class that performs progress calculations(counting)*/private class ProgressThread extends Thread{Handler mHandler;final static int STATE_DONE = 0;final static int STATE_RUNNING = 1;int mState;int total;ProgressThread(Handler h){mHandler = h;}public void run(){mState = STATE_RUNNING;total = 0;while (mState == STATE_RUNNING){try{Thread.sleep(100);}catch (InterruptedException e){Log.e("ERROR", "Thread Interrupted");}Message msg = mHandler.obtainMessage();Bundle b = new Bundle();b.putInt("total", total);msg.setData(b);mHandler.sendMessage(msg);total++;}}/*** sets the current state for the thread, used to stop teh thread*/public void setState(int state){mState = state;}}

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.