建立對話框Creating Dialogsandroid
對話框一般是一個顯示在當前活動前面的小窗口。下面的活動失去焦點而由對話框接受全部的用戶交互。對話框一般被用來當作通知或者運行中的應用程序相關的短暫活動。app
Android API支持下面的對話框對象類型:函數
警告對話框AlertDialog佈局
這個對話框管理0,1,2,或3個按鈕,和/或一個可包含複選框和單選按鈕的可選項列表。這個警告對話框可以組建大多數用戶界面並且是推薦使用的對話框類型。請查看下面的建立一個警告對話框Creating an AlertDialog。動畫
進度對話框ProgressDialogui
用來顯示一個進度輪或進度條。所以它是警告對話框的擴展,它也支持按鈕。請查看下面的Creating a ProgressDialog 。this
日期選擇對話框DatePickerDialog.net
一個容許用戶選擇日期的對話框。請查看Hello DatePicker 指南。線程
時間選擇對話框TimePickerDialog設計
一個容許用戶選擇時間的對話框。請查看Hello TimePicker 指南.
若是你想定製你本身的對話框,你能夠在基礎對話框對象或任何上面列舉的子類對話框上進行擴展並定義一個新的佈局。請查看下面的建立自定義對話框Creating a Custom Dialog章節。
顯示對話框Showing a Dialog
對話框常常做爲活動Activity的一部分來建立和顯示。你一般應該從活動的onCreateDialog(int) 回調方法裏建立對話框。當你使用這個回調函數時,Android系統會有效的設置這個活動爲每一個對話框的全部者,從而自動管理每一個對話框的狀態並掛靠到活動上。這樣,每一個對話框繼承這個活動的特定屬性。好比,當一個對話框打開時,菜單鍵顯示爲這個活動定義的選項菜單,音量鍵修改活動使用的音頻流。
注意: 若是你決定在onCreateDialog()方法以外建立一個對話框,它將不會被附着到活動上。不過,你能夠經過setOwnerActivity(Activity)把它附着到一個活動上。
當你想要顯示一個對話框時,調用showDialog(int) 方法並傳遞一個惟一標識這個對話框的整數。
當對話框第一次被請求時,Android從你的活動中調用onCreateDialog(int),你應該在這裏初始化這個對話框Dialog。這個回調方法被傳以和showDialog(int)相同的ID。當你建立這個對話框後,在方法的最後返回這個對象。
在對話框被顯示以前,Android還調用了可選的回調函數onPrepareDialog(int, Dialog). 若是你想在每一次對話框被打開時改變它的任何屬性,你能夠定義這個方法。這個方法在每次打開對話框時被調用,而onCreateDialog(int) 僅在對話框第一次打開時被調用。若是你不定義onPrepareDialog(),那麼這個對話框將保持和上次打開時同樣。這個方法也被傳遞以對話框的ID,和在onCreateDialog()中建立的對話框對象。
定義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;
}
注意: 在這個例子裏,case語句沒有具體內容,由於這超出了本章討論範圍。
當是時候顯示其中之一的對話框時,使用對話框ID調用showDialog(int):
showDialog(DIALOG_PAUSED_ID);
消除對話框Dismissing a Dialog
當你準備關閉對話框時,你能夠經過對這個對話框調用dismiss()來消除它。若是須要,你還能夠從這個活動中調用dismissDialog(int) 方法,這實際上將爲你對這個對話框調用dismiss() 方法.
若是你想使用onCreateDialog(int) 方法來管理你對話框的狀態(就如同在前面的章節討論的那樣),而後每次你的對話框消除的時候,這個對話框對象的狀態將由該活動保留。若是你決定再也不須要這個對象或者清除該狀態是重要的,那麼你應該調用removeDialog(int)。這將刪除任何內部對象引用並且若是這個對話框正在顯示,它將被消除。
使用消除偵聽器Using dismiss listeners
若是你但願你的應用程序在一個對話框消亡的時候執行一些流程,那麼你應該附着一個on-dismiss偵聽器到對話框上。
首先定義DialogInterface.OnDismissListener 接口。這個接口只有一個方法,onDismiss(DialogInterface),將在對話框消亡的時候被調用。而後簡單的傳遞你的OnDismissListener 實現給setOnDismissListener()。
然而, 請注意對話框也能夠被「取消」。這是一個代表對話框被用戶顯示取消的特殊狀況。這將在用戶按「返回」按鈕時發生,或者這個對話框顯示的調用cancel() (也許經過對話框上的一個「取消」按鈕)。當一個對話框被取消時,這個OnDismissListener 依然會被通知到,可是若是你但願在對話框被顯示取消時被通知到(而不是一般的消除方式),那麼你應該經過setOnCancelListener()註冊一個DialogInterface.OnCancelListener 。
建立警告對話框Creating an AlertDialog
一個警告對話框是對話框的擴展類。它可以構建大多數對話框用戶界面而且是推薦使用的對話框類型。你應該在具有以下特性的時候使用它:
· 一個標題
· 一個文本消息
· 1個,2個或3個按鈕
· 一個可選項列表(可選的複選框或單選按鈕)
爲了建立一個警告對話框,使用AlertDialog.Builder 子類。經過AlertDialog.Builder(Context)獲取一個構造器而後使用這個類的公共方法來定義警告對話框的全部屬性。當獲得構造器後,經過create().方法來獲取警告對話框對象。
下面的題目說明了如何使用AlertDialog.Builder類來定義不一樣的警告對話框屬性。若是你在onCreateDialog()回調函數中使用下面的代碼,你能夠返回結果對話框對象來顯示它。
增長按鈕Adding buttons
爲了建立一個如右圖所示的包含並行按鈕的警告對話框,使用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)。而後,開始函數鏈並設置該對話框爲不能取消not cancelable (所以用戶不能使用返回按鈕關閉這個對話框)。對每一個按鈕,使用任一set...Button() 方法,好比setPositiveButton(),該方法接受按鈕名稱以及一個定義用戶選中按鈕後所採起動做的DialogInterface.OnClickListener。
注意: 你僅能夠爲這個警告對話框添加其中一種按鈕類型。也就是,你不能包含多個「肯定」按鈕。這限制了可能的按鈕數目只能是3個:肯定,中立和否認。這些名字和你按鈕的實際功能是技術上無關的,可是應該能夠幫助你記錄作了什麼。
增長一個列表Adding a list
爲了建立一個帶有可選項列表的警告對話框,如右邊所示,可以使用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() {
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技術。
要建立如右邊所示的一個包含單選項列表的警告對話框,使用前面例子中相同的代碼,不過須要把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() {
public void onClick(DialogInterface dialog, int item) {
Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
}
});
AlertDialog alert = builder.create();
setSingleChoiceItems() 的第二個參數是一個checkedItem整型數值,指示了基於0的缺省選擇項的位置。「-1」表明不會有默認選擇項。
建立進度對話框Creating a ProgressDialog
進度對話框ProgressDialog是AlertDialog類的一個擴展,能夠爲一個未定義進度的任務顯示一個旋轉輪形狀的進度動畫,或者爲一個指定進度的任務顯示一個進度條。這個對話框也能提供按鈕,好比一個取消下載的按鈕。
能夠簡單的經過調用ProgressDialog.show()方法來顯示一個進度對話框。好比, 能夠很簡單的獲得右邊顯示的進度對話框,而沒必要經過onCreateDialog(int)回調管理這個對話框,以下所示:
ProgressDialog dialog = ProgressDialog.show(MyActivity.this, "",
"Loading. Please wait...", true);
第一個參數是應用程序上下文Context,第二個是對話框標題(此處爲空),第三個是信息,最後這個參數代表進度是不是不肯定的(這隻和建立進度條有關,下一章會有描述)。
進度對話框的缺省類型是一個旋轉輪,若是你想建立一個間隔進度,須要更多的代碼,以下章所述。
顯示進度條Showing a progress bar
使用動畫進度條顯示進度:
1. 用類構造器初始化進度對話框,ProgressDialog(Context)。
2. 用setProgressStyle(int)方法設置進度風格爲"STYLE_HORIZONTAL"以及設置其它屬性,好比消息。
3. 當你準備顯示這個對話框時,調用show()或者從onCreateDialog(int)回調中返回ProgressDialog。
4. 你能夠經過調用setProgress(int)設置當前進度百分比或者調用incrementProgressBy(int)方法增長進度值。
好比,你的設置可能看起來像這樣:
ProgressDialog progressDialog;
progressDialog = new ProgressDialog(mContext);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(false);
設置很簡單。大多數建立代碼也用來更新進度。你可能意識到建立另一個線程來完成這個進度報告的工做是有必要的,進度經過一個對象返回給活動的用戶界面線程。若是你對如何經過一個Handler使用另外的線程不熟悉,請參見下面的例子:
Example ProgressDialog with a second thread
這個例子使用了另一個線程來跟蹤進程進度(計數到100)。這個線程在每次進度更新時經過一個句柄Handler發回一條消息Message。主活動而後更新進度對話框。
package com.example.progressdialog;
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.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class NotificationTest extends Activity {
static final int PROGRESS_DIALOG = 0;
Button button;
ProgressThread progressThread;
ProgressDialog progressDialog;
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Setup the button that starts the progress dialog
button = (Button) findViewById(R.id.progressDialog);
button.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
showDialog(PROGRESS_DIALOG);
}
});
}
protected Dialog onCreateDialog(int id) {
switch(id) {
case PROGRESS_DIALOG:
progressDialog = new ProgressDialog(NotificationTest.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 progress
final 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 the thread */
public void setState(int state) {
mState = state;
}
}
}
建立自定義對話框Creating a Custom Dialog
若是你想爲對話框作一個自定義的設計,你能夠爲對話框窗口建立本身的佈局和部件元素。當你定義好佈局後,傳遞根視圖對象或者佈局資源ID給setContentView(View) 方法。
好比,建立如右圖所示對話框:
1. 建立一個XML佈局以custom_dialog.xml保存:
android:id="@+id/layout_root"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
>
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginRight="10dp"
/>
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textColor="#FFF"
/>
這個XML在一個LinearLayout裏定義了一個ImageView 和一個TextView.
2. 設置上面這個佈局做爲對話框的內容視圖併爲這個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);
實例化對話框後,用setContentView(int)設置你的自定義佈局做爲這個對話框的內容視圖,以佈局資源ID做爲參數。如今這個對話框有一個已定義的佈局,你能夠用findViewById(int)方法從佈局中抓取視圖對象。
3. 就這樣了。你如今能夠顯示該對話框了,參見Showing A Dialog中的描述。
以基類對話框建立的對話框必須有一個標題。若是你不調用setTitle(),那麼標題佔用的空間保持爲空,但仍然可見。若是你根本不想要一個標題,那你應該使用警告對話框AlertDialog來建立你的自定義對話框。 然而,由於警告對話框能夠很簡單的經過AlertDialog.Builder 類來建立,你並不須要訪問上面使用的setContentView(int) 方法。相反,你必須使用setView(View)。這個方法接受一個視圖View 對象,因此你須要在XML中擴充佈局的根視圖。
要擴充XML佈局,用getLayoutInflater() 或getSystemService()方法獲取LayoutInflater,而後調用 inflate(int, ViewGroup),這裏第一個參數是佈局資源ID而第二個參數是根視圖的ID。在此處,你可使用擴充佈局來查找視圖對象和爲ImageView和TextView元素定義內容。而後實例化AlertDialog.Builder 並調用setView(View)爲該對話框設置擴充佈局。
下面是一個例子,在一個警告對話框中建立自定義佈局:
AlertDialog.Builder builder;
AlertDialog alertDialog;
Context mContext = getApplicationContext();
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER);
View layout = inflater.inflate(R.layout.custom_dialog,
(ViewGroup) findViewById(R.id.layout_root));
TextView text = (TextView) layout.findViewById(R.id.text);
text.setText("Hello, this is a custom dialog!");
ImageView image = (ImageView) layout.findViewById(R.id.image);
image.setImageResource(R.drawable.android);
builder = new AlertDialog.Builder(mContext);
builder.setView(layout);
alertDialog = builder.create();
在你的自定義佈局中使用警告對話框可讓你利用警告對話框的內置特性好比管理按鈕,可選列表,一個標題,一個圖標等。
想獲取更多信息,請參考Dialog 和 AlertDialog.Builder 類的相關文檔。
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/iefreer/archive/2009/09/22/4581137.aspx