- Android應(yīng)用開發(fā)教程(第2版)
- 羅文主編
- 3400字
- 2021-10-27 15:03:59
3.3 事件處理

08 事件處理
現(xiàn)代的圖形界面都是通過事件來實(shí)現(xiàn)人機(jī)交互的。事件就是用戶對(duì)圖形界面的操作。在Android手機(jī)和平板計(jì)算機(jī)上,事件主要包括鍵盤事件和觸摸事件,鍵盤事件又包括按下、彈起等,觸摸事件又包括按下、彈起、滑動(dòng)等,另外還有重力感應(yīng)事件等。
本節(jié)準(zhǔn)備實(shí)現(xiàn)一個(gè)調(diào)查程序,界面上提供幾種開發(fā)語言的選擇列表,如Java、C#、Basic等,使用時(shí)除了單擊相應(yīng)控件進(jìn)行選取之外,還可以通過在鍵盤上滑動(dòng)進(jìn)行選項(xiàng)的“反選”操作。當(dāng)用戶最終單擊“確定”按鈕后,系統(tǒng)將進(jìn)行一個(gè)簡短的提示,告知用戶所選擇的項(xiàng)目數(shù)量。
3.3.1 事件監(jiān)聽處理機(jī)制
Android中的事件處理分為基于監(jiān)聽接口的事件處理和基于回調(diào)機(jī)制的事件處理兩種。
1.基于監(jiān)聽接口的事件處理
基于監(jiān)聽接口的事件處理涉及以下三個(gè)對(duì)象。
? EventSource(事件源):事件發(fā)生的場所,通常為各個(gè)組件。
? Event(事件):事件封裝了界面組件上發(fā)生的特定事情,通常是用戶的一次操作,可以通過Event對(duì)象取得具體信息。
? EventListener(事件監(jiān)聽器):負(fù)責(zé)監(jiān)聽事件源發(fā)生的事情,并做出響應(yīng)。事件監(jiān)聽器是用來處理事件的對(duì)象,實(shí)現(xiàn)了特定的接口,根據(jù)事件不同重寫不同的事件處理方法來響應(yīng)事件。
View類中的EventListener是一個(gè)帶有回調(diào)方法的接口,而所有的組件都繼承自View類,所以不同的組件類實(shí)現(xiàn)該接口以完成不同的監(jiān)聽。常見的監(jiān)聽接口處理方法有以下幾種。
? 單擊事件:OnClickListener接口的public void onClick(View v)處理。
? 長按事件:OnLongClickListener接口的public boolean onLongClick(View v)處理。
? 控件焦點(diǎn)改變事件:OnFocusChangeListener接口的onFocusChange(View v, Boolean hasFocus)處理。
? 鍵盤事件:OnKeyListener接口的public boolean onKey(View v, int keyCode, KeyEvent event)處理。
? 觸摸事件:OnTouchListener接口的public boolean onTouch(view v, MotionEvent event)處理。
? 上下文菜單顯示事件:OnCreateContexMenuListener接口的public void onCreateContexMenu (ContexMenu menu, View v, ContexMenuInfo info)處理。
在Android中需要將事件源和事件監(jiān)聽器聯(lián)系到一起,這就是事件源注冊(cè)監(jiān)聽。一個(gè)典型的事件監(jiān)聽的操作過程如下。
1)在MainActivity類中定義一個(gè)成員變量用于引用需要監(jiān)聽的組件。
2)建立一個(gè)繼承自類似OnClickListener接口的類,主要為了重寫其中的事件響應(yīng)方法。
3)在MainActivity類的onCreate()方法中為按鈕注冊(cè)監(jiān)聽,這樣當(dāng)基于該組件的事件發(fā)生后,就會(huì)調(diào)用相應(yīng)重寫的方法進(jìn)行處理了。
例如需要為按鈕添加單擊事件監(jiān)聽,處理過程如下。
1)通常在Activity的onCreate()方法中取得按鈕對(duì)象(假設(shè)按鈕的id為button1)。

2)為bt按鈕對(duì)象綁定單擊事件監(jiān)聽對(duì)象,此時(shí)需要導(dǎo)入相應(yīng)的程序包,即在代碼文件頭部添加import android.view.View.OnClickListener語句。

3)設(shè)置setOnClickListener()方法的參數(shù)。
該方法有一個(gè)唯一的參數(shù)是OnClickListener對(duì)象,一般采用動(dòng)態(tài)的方式構(gòu)建這個(gè)對(duì)象,即:new OnClickListener(){}。將上面兩者結(jié)合起來,得到代碼如下。

4)在新構(gòu)建的對(duì)象中重寫OnClick()方法,作為單擊事件的響應(yīng)程序。該方法有一個(gè)View類型的參數(shù),表示被單擊的按鈕本身。將相應(yīng)事件的執(zhí)行代碼安排在這個(gè)方法中,代碼如下。

將上述代碼合并到一起,即:

這段代碼看起來比較復(fù)雜,卻是事件響應(yīng)的基本模式,其他控件的事件響應(yīng)程序的布局基本沿用了上述方法。
除OnClickListener外,類似的監(jiān)聽器還有OnLongClickListener(用戶長按組件)等。一般,事件監(jiān)聽函數(shù)以set開頭,以Listener結(jié)尾;事件監(jiān)聽函數(shù)的參數(shù)構(gòu)造函數(shù)以O(shè)n開頭,以Listener結(jié)尾;需要重寫的事件相應(yīng)程序以O(shè)n開頭。特別值得注意的是,需要針對(duì)不同的監(jiān)聽載入相應(yīng)的命名空間。初學(xué)者很容易遺漏第二條語句之后的分號(hào)。
2.基于回調(diào)機(jī)制的事件處理
在回調(diào)機(jī)制中,事件源和事件監(jiān)聽器是統(tǒng)一的,或者說不需要專門指定事件監(jiān)聽器,當(dāng)用戶在組件上激發(fā)某個(gè)事件時(shí),組件自己特定的方法將會(huì)負(fù)責(zé)處理該事件。
在使用基于回調(diào)機(jī)制處理組件上所發(fā)生的事件時(shí),需要為該組件提供相應(yīng)的事件處理方法,而Java又是一種靜態(tài)語言,無法為每一個(gè)對(duì)象動(dòng)態(tài)地加入方法,因此只能通過繼承組件類并重寫該類的事件處理方法來實(shí)現(xiàn)。Android中每個(gè)組件都有自己處理特定事件的回調(diào)方法,如onKeyDown()、onKeyUp()、onTouchEvent()方法等,可以通過重寫這些回調(diào)方法來實(shí)現(xiàn)對(duì)應(yīng)的事件處理。
自定義組件的一般步驟如下。
1)定義自定義組件的類名,并繼承某個(gè)組件類或其子類。
2)重寫父類的一些方法(回調(diào)方法)。依據(jù)業(yè)務(wù)需要重寫父類的部分回調(diào)方法,比如onDraw()方法用于實(shí)現(xiàn)界面顯示,其他方法還有onSizeChanged()、onKeyDown()、onKeyUP()等。除了重寫回調(diào)方法外,通常還需要提供一個(gè)構(gòu)造器,當(dāng)Java代碼創(chuàng)建該組件或依據(jù)XML布局文件載入并構(gòu)建界面時(shí)都將調(diào)用該構(gòu)造器。
3)使用自定義的組件。既可以通過Java代碼來創(chuàng)建,也可通過XML布局文件創(chuàng)建。注意在XML布局文件中,該組件的標(biāo)簽是完整的包名+類名,不再是原來的類名。
代碼示例如下:


3.3.2 鍵盤事件
一個(gè)標(biāo)準(zhǔn)的Android設(shè)備包含了多個(gè)能夠觸發(fā)事件的物理按鍵,Android中的物理按鍵事件處理是基于回調(diào)機(jī)制的,提供的回調(diào)方法有onKeyUp()、onKeyDown()、onKeyLongPress()。在事件處理代碼中,為區(qū)分按鍵設(shè)備,Android為每個(gè)按鍵定義了唯一編碼,各個(gè)物理按鍵對(duì)應(yīng)的編碼如表3-15所示。
表3-15 Android設(shè)備可用的物理按鍵編碼

例如,以下代碼處理了鍵盤返回鍵的事件響應(yīng)。

3.3.3 觸摸事件
用戶在觸摸屏上的滑動(dòng)觸摸事件,一般使用OnTouchListener接口定義的監(jiān)聽器,在監(jiān)聽器中重寫public boolean onTouch(View v,MotionEvent event)方法可以處理用戶在觸摸屏上的動(dòng)作事件。View類是其他Android組件的父類,在該類中,定義了setOnTouchListener()方法用來為組件設(shè)置觸摸事件監(jiān)聽器。在監(jiān)聽處理方法中通過event.getAction()可以獲取用戶的觸摸動(dòng)作。Android提供了用戶在屏幕上的觸摸事件編碼,如表3-16所示。
表3-16 屏幕觸摸事件編碼

例如以下代碼實(shí)現(xiàn)當(dāng)用戶觸摸屏幕后彈出一個(gè)消息提示的功能。

3.3.4 重力感應(yīng)事件
1.Android重力感應(yīng)介紹
在Android的開發(fā)中常用的基礎(chǔ)傳感器有8種,分別是加速度傳感器(Accelerometer)、陀螺儀傳感器(Gyroscope)、環(huán)境光照傳感器(Light)、磁力傳感器(Magnetic field)、方向傳感器(Orientation)、壓力傳感器(Pressure)、距離傳感器(Proximity)、溫度傳感器(Temperature)。隨著技術(shù)的發(fā)展,Android支持的傳感器種類越來越多,達(dá)20余種。但是不是每一款真機(jī)都支持這些傳感器。因?yàn)楹芏喙δ苡脩舾静魂P(guān)心,所以開發(fā)商會(huì)把某些功能屏蔽掉。
重力感應(yīng)是現(xiàn)在手機(jī)中常用的一個(gè)器件,使用的其實(shí)是加速度傳感器。當(dāng)手機(jī)靜止時(shí),加速度就是重力,所以一般也叫作重力傳感器。這個(gè)硬件可以感應(yīng)加速度的變化,轉(zhuǎn)化為數(shù)據(jù)提供給系統(tǒng)。系統(tǒng)可以根據(jù)這些數(shù)據(jù)做一些事情。最常見的應(yīng)用就是根據(jù)重力旋轉(zhuǎn)屏幕。
2.Android重力感應(yīng)系統(tǒng)的坐標(biāo)系
如圖3-15所示,Android重力感應(yīng)坐標(biāo)系統(tǒng)以屏幕的左下方為原點(diǎn)(在二維編程中,是以屏幕左上方為原點(diǎn)的,這個(gè)值得注意),箭頭指向的方向?yàn)檎?。?10到10,可用浮點(diǎn)小數(shù)表示,例如以下情形的坐標(biāo)變化:

圖3-15 Android重力感應(yīng)坐標(biāo)系統(tǒng)
? 手機(jī)屏幕向上(Z軸朝天)水平放置的時(shí)候,(x,y,z)的值分別為(0,0,10)。
? 手機(jī)屏幕向下(Z軸朝地)水平放置的時(shí)候,(x,y,z)的值分別為(0,0,-10)。
? 手機(jī)屏幕向左側(cè)放(X軸朝天)的時(shí)候,(x,y,z)的值分別為(10,0,0)。
? 手機(jī)豎直(Y軸朝天)向上的時(shí)候,(x,y,z)的值分別為(0,10,0)。
其他的情形照此類推,遵循的規(guī)律是:朝天的就是正數(shù),朝地的就是負(fù)數(shù)。利用x,y,z三個(gè)值求三角函數(shù),就可以精確檢測手機(jī)當(dāng)前的狀態(tài)了。
3.檢測重力感應(yīng)事件
首先獲得一個(gè)SensorManager對(duì)象:SensorManager manager=(SensorManager) this.getSystem Service(Context.SENSOR_SERVICE)。手機(jī)中的所有傳感器都是通過SensorMannager來訪問的,調(diào)用上下文的getSystemService(SENSOR_SERVICE)方法就可以獲得當(dāng)前手機(jī)的所有傳感器管理對(duì)象。然后通過這個(gè)SensorManager對(duì)象來獲得一個(gè)Sensor的列表:List<Sensor> sensors =manager.getSensorList(Sensor.TYPE_ACCELEROMETER)。其中,Sensor.TYPE_ACCELEROMETER參數(shù)用于指明獲取加速度感應(yīng)對(duì)象。
在Android中,使用重力感應(yīng)功能還需要使用SensorEventListener接口,其中有兩個(gè)接口方法,onSensorChanged()和onAccuracyChanged(),一般都是在onSensorChanged()方法中做事務(wù)處理。
實(shí)際使用時(shí),還要在SensorManager對(duì)象上注冊(cè)SensorEventListener監(jiān)聽器,例如:manager.registerListener(listener,sensor,rate),其中l(wèi)istener就是SensorEventListener監(jiān)聽器對(duì)象,sensor是前面獲取的Sensor實(shí)例,rate是指延遲時(shí)間。最后要取消重力感應(yīng)時(shí),調(diào)用manager.unregisterListener(listener)即可。
如下的代碼示例實(shí)現(xiàn)了一個(gè)當(dāng)手機(jī)重力狀態(tài)發(fā)生變化時(shí)給出提示的效果。

3.3.5 實(shí)例3:調(diào)查問答
1.新建項(xiàng)目,增添組件
在AS中新建項(xiàng)目,應(yīng)用程序命名為“調(diào)查問答”,項(xiàng)目命名為“ch03_03”,其他項(xiàng)取默認(rèn)值。
在res\value\string.xml文件中新增字符串資源,用于界面顯示,參考代碼如下。

在MainActivity類中對(duì)按鈕單擊事件進(jìn)行響應(yīng),采用基于監(jiān)聽接口的事件處理方式,參考代碼如下。

在監(jiān)聽器接口OnClickListener繼承的自定義類中的onClick()方法中具體完成選中項(xiàng)目的統(tǒng)計(jì),并以Toast形式進(jìn)行顯示。
在MainActivity類中對(duì)屏幕觸摸事件進(jìn)行相應(yīng)處理,采用基于回調(diào)機(jī)制的事件處理方式,參考代碼如下。

在重寫的onTouchEvent()方法中判定如果用戶觸摸完畢并已經(jīng)抬起手指(MotionEvent.ACTION_UP)就對(duì)復(fù)選框進(jìn)行反選操作,選中原來沒有選中的項(xiàng)目,取消已經(jīng)處于選定狀態(tài)的項(xiàng)目。這樣用戶即便沒有在屏幕上滑動(dòng),僅僅在屏幕上單擊一下,也會(huì)執(zhí)行這個(gè)“反選”操作。
2.設(shè)計(jì)布局
在res\layout\activity_main.xml中進(jìn)行界面設(shè)計(jì),此處需要一個(gè)文本顯示組件,三個(gè)復(fù)選框組件,一個(gè)按鈕組件,參考代碼如下。


3.參考代碼


選擇兩項(xiàng)的情況如圖3-16所示;當(dāng)在屏幕上滑動(dòng)從屏幕抬起手指時(shí)進(jìn)行反選,如圖3-17所示。選擇完畢后,單擊“確定”按鈕,出現(xiàn)提示信息。

圖3-16 選擇兩項(xiàng)示例

圖3-17 觸摸事件進(jìn)行反選
- Serverless架構(gòu):從原理、設(shè)計(jì)到項(xiàng)目實(shí)戰(zhàn)
- 圖解電子技術(shù)速學(xué)速用
- 音箱設(shè)計(jì)與制作指南
- 半導(dǎo)體制造技術(shù)導(dǎo)論
- 目標(biāo)特性與傳感原理
- 電子裝配工藝實(shí)訓(xùn):項(xiàng)目教程
- Android移動(dòng)應(yīng)用開發(fā)項(xiàng)目教程
- 應(yīng)用電工電子技術(shù)(上冊(cè))
- PTN分組傳送設(shè)備組網(wǎng)與實(shí)訓(xùn)(第2版)
- 電工與電子技術(shù)及技能訓(xùn)練
- NFC技術(shù)原理與應(yīng)用
- 密碼術(shù)語
- 5G安全體系與關(guān)鍵技術(shù)
- 基于Android Studio的案例教程(第2版)
- 高頻開關(guān)電源設(shè)計(jì)與應(yīng)用實(shí)例