編輯:Android開發實例
本文是對網上的文章《Android開發指南-用戶界面-對話框》的部分內容進行簡化,並加上自己的某些理解。裡面的相同內容,版權歸原翻譯作者所有。
對話框經常作為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);
當你准備關閉對話框時,你可以通過對這個對話框調用dismiss()來消除它。如果需要,你還可以從這個Activity中調用dismissDialog(int id) 方法,這實際上將為你對這個對話框調用dismiss() 方法。
如果你想使用onCreateDialog(int id) 方法來管理你對話框的狀態(就如同在前面的章節討論的那樣),然後每次你的對話框消除的時候,這個對話框對象的狀態將由該Activity保留。如果你決定不再需要這個對象或者清除該狀態是重要的,那麼你應該調用removeDialog(int id)。這將刪除任何內部對象引用而且如果這個對話框正在顯示,它將被消除。
如果你希望你的應用程序在一個對話框消亡的時候執行一些流程,那麼你應該附著一個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.Builder 子類。通過AlertDialog.Builder(Context)獲取一個構造器然後使用這個類的公共方法來定義警告對話框的所有屬性。當得到構造器後,通過create().方法來獲取警告對話框對象。有時我是不調用create()的,而是在設置好了後直接調用show()顯示AlertDialog。
這就是我一開始很想知道的究竟如何添加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。
- 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”代表不會有默認選擇項。
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函數,這些函數沒有明確哪個是正面/中立/負面的,由我們決定。
而選擇動畫進度條顯示進度:
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機制!
創建自定義對話框,首先要創建一個Layout xml 文件,在此不啰嗦了。然後加載Layout有兩種方法,也是非常熟悉的那兩種方法:
1. setContentView(int resources id)
2. 利用LayoutInflater加載
官方還提示我們,一般使用Dialog類來創建對話框,是需要setTitle的,不設置的話,標題占用的空間保持為空,但仍然可見。而不想要那個標題,那應該使用警告對話框AlertDialog來創建自定義對話框。然而,因為警告對話框可以很簡單的通過AlertDialog.Builder 類來創建,你並不需要訪問上面使用的setContentView(int) 方法。相反,你必須使用setView(View),則需要使用LayoutInflater來加載Layout得到View。
具體代碼參考http://androidappdocs.appspot.com/guide/topics/ui/dialogs.html
Android應用程序可以在許多不同地區的許多設備上運行。為了使應用程序更具交互性,應用程序應該處理以適合應用程序將要使用的語言環境方面的文字,數字,文件等。在本章中,我
在 Android 中,多數情況下每個程序都是在各自獨立的 Linux 進程中運行的。當一個程序或其某些部分被請求時,它的進程就“出生”了;當這個程序沒有必要再運
南丁格爾玫瑰圖 在常規圖表中實在很驚艷,但我初看沒看懂,一查原來南丁格爾這麼偉大,確實值得尊敬。 再仔細研究了下這種圖的構成,發現原來就是把柱形圖的柱形換成了扇形
登錄應用程序的屏幕,詢問憑據登錄到一些特定的應用。可能需要登錄到Facebook,微博等本章介紹了,如何創建一個登錄界面,以及如何管理安全問題和錯誤嘗試。首先,必須定義兩