標籤:android dilaog popupwindow alertdialog progressdialog
Android之Dialog分析
以Dialog為引導,Android的彈出式訊息一共是三種(據我所知):Dialog,tocast,notification 其三種彈出式訊息各有所長。今天重點是分析其中的Dialog。Android的Dialog是android介面編程的重點。當然android被稱之為“頁程式”就更體現頁面編程,UI線程瞭解的重要性了。
本文的目錄結構:
1、Android中的幾種Dialog
2、Dialog的建立方式
3、Android的警告對話方塊AlertDialog
4、Android的進度框ProgressDialog
5、日期選擇框& 時間選擇框
6、對話方塊風格的視窗
7、popupwindow
建立對話方塊一般是出現在當前Activity之上的一個小視窗,此時Activity失去焦點,轉由對話方塊接受使用者的互動(觸摸響應事件)
首先看一看Dialog的類圖,由此可以更清晰的看到控制項的屬性繼承關係
一、Android中的幾種Dialog:
1、 自訂:Dialog
2、 警告框:AlertDialog
3、 進度框:ProgressDialog
4、 日期選擇框:DatePickerDialog
5、 時間選擇框:TimePickerDialog
Android的其他幾種類似的視窗
1、 對話方塊風格的視窗
2、 Popupwindow
二、Dialog的建立方式總的來說是兩種:
1、 直接new一個Dialog對象,然後調用Dialog對象的show()和dismiss()方法來控制對話方塊的顯示和隱藏
2、 在Activity的onCreateDialog(intid)方法中建立Dialog對象並返回,然後調用Activity的showDialog(int id)和dismissDialog(int id)來顯示和隱藏對話方塊
這兩者的區別在於通過第二種方式建立的對話方塊會繼承Activity的屬性,並且Android系統會自動管理每個對話方塊的狀態並將它們和Activity串連,這樣當開啟一個對話方塊時,Menu鍵會顯示Activity的菜單,音量鍵會調整Activity當前使用的音頻流的音量。同時第二種方式在Activity中有父類方法可實現:
onPrepareDialog(int, Dialog):如果希望每次顯示對話方塊的時候有動態更改的內容,那麼修改這個函數
onCreateDialog(int)當一個對話方塊第一次被請求時,Android調用這個方法,這是初始化對話方塊的地方,建立對話方塊之後,將返回被建立的對象
dismissDialog(int)二者的效果是一樣的。
removeDialog(int)如果你使用onCreateDialog(int)來管理你的對話方塊的狀態, 那麼每次你的對話方塊被解除時, 該對話方塊對象的狀態會被Activity儲存. 如果你決定你不再需要這個對象或者需要清除對話方塊的狀態, 那麼你應該調用這個方法。這將把所有該對象的內部引用移除。
三、Android的警告對話方塊AlertDialog
其實警告對話方塊AlertDialog是作為Dialog的一個拓展,方便與應用各種固定模式的對話方塊中;確定的產生對話方塊,包括標題,內容,選項,按鈕等的設定和響應等;這很方便,但是實際實現中卻也有自己的短板:theme改變不了(貌似是固定的,比如想設定Dialog的背景色透明就不行,可能我還不會用全)。
下面介紹AlertDialog的基本用法:
AlertDialog產生的對話方塊可分為如下四個地區:
·產生對象 使用建立 AlertDialog.Builder對象
·表徵圖區 調用AlertDialog.Builder的setIcon方法設定
·標題區 調用AlertDialog.Builder的setTitle()或setCustomTitle()方法設定標題
·內容區 調用AlertDialog.Builder的相關設定方法設定對話方塊內容
·按鈕區 調用AlertDialog.Builder的setPositiveButton()、setNegativeButton() 或setNeutralButton()方法添加多個按鈕。
調用AlterDialog.Builder的create()方法建立AlertDialog對象,再調用AlertDialog對象的show方法將該對話方塊顯示出來。
以上的是AlertDialog的固定模式;
具體更改內容區的顯示內容可達到不同的目的,AlertDialog提供如下六中方法來指定對話方塊的內容。
setMessage():設定對話方塊內容為簡單的常值內容
setItems():設定對話方塊內容為簡單清單項目
setSingleChoiceItems():設定對話方塊內容為單選清單項目
setMultiChoiceItems():設定對話方塊內容為多選清單項目
setAdapter():設定對話方塊內容為自訂欄表項
setView():設定對話方塊內容為自訂的View
以上的這六種對話方塊基本就是可以滿足需要了,詳細的實現可參考博文:http://www.oschina.net/question/54100_32486
四,Android的進度框ProgressDialog
一個ProgressDialog(進度對話方塊)是AlertDialog的擴充。它可以顯示一個進度的動畫——進度環或者進度條。這個對話方塊也可以提供按鈕,例如取消一個下載等。
進度框Dialog是一個明顯的直接面對進度框的Dialog,這樣做是免除了自訂progress 的Dialog或是AlertDialog的複雜。
其具體實現有兩種方式:
1、只是建立簡單的進度對話方塊,調用ProgressDialog提供的靜態show()方法顯示對話方塊即可
2、是new ProgressDailog(this)擷取對象,然後設定屬性等
五、日期選擇框 & 時間選擇框
日期選擇框(DatePickDialog)和時間選擇框(TimePickerDialog)的使用是比較簡單的,兩個步驟:
1、 都是先new出DatePickDialog & TimePickerDialog執行個體,調用其show()方法即可顯示出來。
2、 為其綁定監聽器;設定事件監聽器,從而擷取使用者佈建的事件(時間& 日期)
在new出對象的同時,監聽器是必須的
NewDtePickerDialog(this, new DatePickerDialog.OnDateSerListener(){…在實現方法中擷取日期…});
NewTimerPickerDialog(this, new TimePcikerDialog.OnTimeSetListener(){…在實現方法中擷取時間…});
六、對話方塊風格的視窗
其實本質上仍然是視窗,並不能算是Dialog;其本質上是Activity,只是將它做成了對話方塊風格而已。
這個是在Activity中配置相關theme主題就ok了。
<activity android:name=".ServerConfigDialogActivity" android:label="@string/app_name"android:theme="@android:style/Theme.Dialog"> <intent-filter> <action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/></intent-filter></activity>
七、popupwindow
Popupwindow也是可以建立類似對話方塊風格的視窗的,使用簡單,兩個步驟:
1、 popupwindow的構造器建立popupwindow對象
2、 顯示的方式有兩種:
1、 作為某控制項的下拉項:showAsDropDown(View v)
2、 指定位置展示:showAtLocation()在指定位置顯示出來
(樣本中的重點是點擊外來事件的時候popupwindow會不會消失的問題,設定背景很重要)
packagecom.example.hellopopupwindow; importandroid.os.Bundle;importandroid.app.Activity;importandroid.content.Context;importandroid.util.Log;importandroid.view.LayoutInflater;importandroid.view.MotionEvent;importandroid.view.View;import android.view.View.OnClickListener;importandroid.view.View.OnTouchListener;importandroid.view.ViewGroup.LayoutParams;importandroid.widget.Button;importandroid.widget.PopupWindow;importandroid.widget.Toast; public classMainActivity extends Activity { private Context mContext = null; @Override protected void onCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mContext = this; Button button = (Button)findViewById(R.id.button); button.setOnClickListener(newView.OnClickListener() { @Override public void onClick(View view) { showPopupWindow(view); } }); } private void showPopupWindow(View view) { // 一個自訂的布局,作為顯示的內容 View contentView =LayoutInflater.from(mContext).inflate( R.layout.pop_window, null); // 設定按鈕的點擊事件 Button button = (Button) contentView.findViewById(R.id.button1); button.setOnClickListener(newOnClickListener() { @Override public void onClick(View v) { Toast.makeText(mContext,"button is pressed", Toast.LENGTH_SHORT).show(); } }); final PopupWindow popupWindow = newPopupWindow(contentView, LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT, true); popupWindow.setTouchable(true); popupWindow.setTouchInterceptor(newOnTouchListener() { @Override public boolean onTouch(View v,MotionEvent event) { Log.i("mengdd","onTouch : "); return false; // 這裡如果返回true的話,touch事件將被攔截 // 攔截後 PopupWindow的onTouchEvent不被調用,這樣點擊外部地區無法dismiss } }); // 如果不設定PopupWindow的背景,無論是點擊外部地區還是Back鍵都無法dismiss彈框 // 我覺得這裡是API的一個bug popupWindow.setBackgroundDrawable(getResources().getDrawable( R.drawable.selectmenu_bg_downward)); // 設定好參數之後再show popupWindow.showAsDropDown(view); }}
Android之Dialog分析