摘要
本文是手勢識別輸入事件處理的完整學(xué)習(xí)記錄。內(nèi)容包括輸入事件InputEvent響應(yīng)方式,觸摸事件MotionEvent的概念和使用,觸摸事件的動作分類、多點(diǎn)觸摸。根據(jù)案例和API分析了觸摸手勢Touch Gesture的識別處理的一般過程。介紹了相關(guān)的GestureDetector,Scroller和VelocityTracker。最后分析drag和scale等一些手勢的識別。
輸入源分類
雖然android本身是一個完整的系統(tǒng),它主要運(yùn)行在移動設(shè)備的特性決定了我們在它上面開的app絕大數(shù)屬于客戶端程序,主要目標(biāo)就是顯示界面處理交互,這點(diǎn)和web前端以及桌面上的應(yīng)用類似。
作為“客戶端程序”,編寫的大部分功能就是處理用戶交互。不同系統(tǒng)(對應(yīng)不同設(shè)備)可支持的用戶交互各有不同。
android可以運(yùn)行在多種設(shè)備,從交互輸入上看,InputDevice.SOURCE_CLASS_xxx常量標(biāo)識了sdk所支持的幾種不同輸入源的設(shè)備。有:觸屏,物理/虛擬按鍵,搖桿,鼠標(biāo)等,下面的討論針對最廣泛的交互——觸屏( SOURCE_TOUCHSCREEN)。
觸屏設(shè)備從交互設(shè)計上看就是各種手勢,有點(diǎn)擊,雙擊,滑動,拖拽,縮放等等交互定義,本質(zhì)上它們都是基礎(chǔ)的幾種觸摸事件的不同模式的組合。
在安卓觸屏系統(tǒng)中,支持單點(diǎn)、多點(diǎn)(點(diǎn)通常就是手指)觸摸,每個點(diǎn)有按下,移動和抬起。
觸屏交互的處理分不同觸屏操作——手勢的識別,然后是根據(jù)業(yè)務(wù)對應(yīng)不同處理。為了響應(yīng)不同的手勢,首先就需要識別它們。識別過程就是跟蹤收集系實(shí)時提供的反應(yīng)用戶在屏幕上的動作的"基本事件",然后根據(jù)這些數(shù)據(jù)(事件集合)來判定出各種不同種類的高級別的“動作”。
android.view.GestureDetector提供了對onScroll、onLongPress、onFling等幾個最常見動作的監(jiān)聽。而自己的app根據(jù)需要可以通過實(shí)現(xiàn)自己的GestureDetector類型來識別出類似Drag、Scale這樣的交互動作。
手勢識別是智能手機(jī)和平板等觸屏設(shè)備的主流交互/輸入方式,不同于PC上的鍵盤和鼠標(biāo)。
輸入事件
用戶交互產(chǎn)生的輸入事件最終由InputEvent的子類來表示,目前包括KeyEvent(Object used to report key and button events)和MotionEvent(Object used to report movement (mouse, pen, finger, trackball) events.)。
接收InputEvent的地方有很多,根據(jù)框架對事件的傳播路徑依次有Activity、Window、View(ViewTree的一條路徑:view stack)。
多數(shù)情況下都是在用戶交互的具體View中接收并處理這些輸入事件。
View的事件處理有2種方式,一種是添加監(jiān)聽器(event listener),另一種是重寫處理器方法( event handler)。前者比較方便,后者在自定義View時根據(jù)需要去重寫,而且CustomView也可以根據(jù)需要定義自己的處理器方法,或提供監(jiān)聽接口。
事件監(jiān)聽
事件監(jiān)聽接口都是只包含一個方法的interface,如:
// 在View.java中 public <