国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android觸屏事件和MotionEvent詳解

2019-10-22 18:25:46
字體:
來源:轉載
供稿:網友

Android屏幕操作

屏幕是用戶和Android設備交互的主要媒介,屏幕分為觸屏和非觸屏。Android設備目前有四種類型:Android Phone,Android Tablet,Android Wear和Android TV。Android TV大都使用非觸屏,其他三類設備則大都使用觸屏。對非觸屏設備,用戶可以通過鍵盤鼠標或遙控器在屏幕上操作。對觸屏設備,用戶主要通過手指或觸控筆等工具在屏幕上操作,當然也可以通過外接的鍵盤,鼠標和軌跡球等工具來操作。

Android屏幕交互事件

用戶在設備屏幕上的所有操作都會轉換為各類屏幕交互事件。Android屏幕交互事件主要有如下幾種類型。

  • key event 鍵盤、遙控器按鍵,鼠標點擊會生成按鍵事件(key event)
  • hover event 鼠標在屏幕上的停留、滑動會產生hover event
  • scroll event 鼠標滾輪的滾動會生成scroll event
  • touch event 對觸屏設備,當用戶用手指或觸控筆在設備屏幕上操作時會產生觸屏事件(touch event)。

為了方便理解和簡化描述,后文在介紹時會統一用手指操作來代指所有的觸屏操作。例如“當手指接觸屏幕時產生此事件”,并不表示只能用手指接觸屏幕才會產生此事件,而是需要理解為“當手指,觸控筆等工具接觸屏幕時都會產生此事件”。

觸屏事件類型

按照動作來分,可以將觸屏事件可以分為以下三類

  1. 手指按到屏幕上
  2. 手指在屏幕上移動
  3. 手指離開屏幕

其中手指按到屏幕上和手指離開屏幕一定是成對出現的,在這中間會出現不定次數的手指在屏幕上移動的事件。

觸屏事件序列

在Android系統中,從手指按到屏幕上開始,到手指離開屏幕,這個過程中產生的一系列觸屏事件構成了一個事件序列(也可以稱為事件流)。對多點觸屏事件,則是從第一個手指按到屏幕上開始,到最后一個手指離開屏幕為止。

一個觸屏事件序列第一個事件一定是手指按到屏幕上,最后一個事件一定是手指離開屏幕。用戶在設備屏幕上的所有觸屏操作最終都會轉換為若干個這樣的事件序列。

理解觸屏事件序列的概念非常重要,Android中對觸屏事件的處理很多時候需要以事件序列為單位進行考察。

Android觸屏事件在代碼中的表示

在Android系統中使用MotionEvent對象來表示一個觸屏事件,當用戶用手指在屏幕上操作時,會產生一系列的MotionEvent對象。但是需要注意的是,產生了一個MotionEvent對象并不表示這一定是一個觸屏操作,MotionEvent不僅可以用來表示touch event,還可以表示hover event,scroll event。也就是說,除了key event之外的其他屏幕交互事件都用MotionEvent來表示(key event用KeyEvent對象表示)。

在MotionEvent類中將產生此次事件的動作稱為motion,將產生此動作的主體(如手指,鼠標等)稱為pointer。一個MotionEvent對象中可以包含一個或多個pointer,每個pointer都包含id,index,位置,大小,方向等屬性。在一個觸屏事件序列的多個事件中,同一個pointer擁有相同的id,但是index可以不同。

這里只討論MotionEvent中關于touch event的部分。在MotionEvent對象中主要包含了如下信息:

1.操作類型(action code)

MotionEvent提供了getActionMasked()方法來獲取此次操作的類型,它是一個int型數值。除了getActionMasked()外還有一個getAction()方法,它和getActionMasked()的區別會在后面介紹。

在MotionEvent類中定義了一系列的int常量來表示各種預定義的操作類型。列舉如下。

 

事件類型常量 含義說明
ACTION_DOWN 當手指接觸屏幕時產生此事件,在多點觸摸時,只有第一個手指接觸屏幕時才會產生此事件,中間其他手指接觸屏幕不會產生此事件。它表示一個觸屏事件序列的開始。
ACTION_UP 當手指離開屏幕時產生此事件,在多點觸摸時,只有最后一個手指(這個手指并不一定是產生ACTION_DOWN事件的那個手指)離開屏幕時才會產生此事件,中間其他手指離開屏幕不會產生此事件。它表示一個觸屏事件序列的結束。
ACTION_MOVE 當手指在屏幕上滑動時產生此事件, 在多點觸摸時,每個手指的滑動都會產生一個此事件
ACTION_POINTER_DOWN 只有在多點觸摸時才會產生此事件,在一個觸屏事件序列中,除第一個接觸屏幕的手指外,其他手指接觸屏幕時會產生此事件。
ACTION_POINTER_UP 同樣只有在多點觸摸時才會產生此事件,在一個觸屏事件序列中,除最后一個離開屏幕的手指外,其他手指離開屏幕時會產生此事件。
ACTION_CANCEL 這個事件比較特殊,它和上述事件都不一樣,上述事件都是由用戶在屏幕上操作所觸發的,但是這個事件是由系統自動產生的。當一個事件序列需要提前終止的時候由系統自動產生此事件。正常來說,一個事件序列應該以最后一個手指離開屏幕,也就是ACTION_UP作為結束,但是在某些情況下,事件序列需要被提前終止。這通常是因為處理這個事件序列的View對象的Parent對象在事件序列結束之前主動攔截了后續的事件。此外,如果處理這個事件序列的View對象從窗口中被移除了,它也會收到ACTION_CANCEL事件。例如處理這個事件序列的View對象所在的Activty被finish(),所在的Dialog被dismiss(),或者被其Parent View Remove了。在這些情況下,雖然這時手指還停留在屏幕上,但View對象將無法再接收到后續的觸屏事件,這時它會收到ACTION_CANCEL事件,表示事件序列由于外在原因需要提前終止。

 

結合上面觸屏事件序列的描述可以知道,一個正常的觸屏事件序列一定是以ACTION_DOWN為開始,以ACTION_UP為結束,中間可以有0個或多個ACTION_MOVE, 如果是多點觸摸,中間還會有若干次的ACTION_POINTER_DOWN和ACTION_POINTER_UP。ACTION_POINTER_DOWN和ACTION_POINTER_UP一定是數量相對的。

一個提前終止的觸屏事件序列一定是以ACTION_DOWN為開始,以ACTION_CANCEL為結束,中間可以有0個或多個ACTION_MOVE, 如果是多點觸摸,中間還會有若干次的ACTION_POINTER_DOWN和ACTION_POINTER_UP。ACTION_POINTER_DOWN和ACTION_POINTER_UP的數量可能不同。

getAction()和getActionMasked()的區別:對ACTION_POINTER_DOWN和ACTION_POINTER_UP之外的事件,getAction()返回值和getActionMasked()是相同的。對ACTION_POINTER_DOWN和ACTION_POINTER_UP,getAction()返回值和getActionMasked()返回值稍有不同。getAction()返回值包含了操作類型和產生此事件的pointer對應的pointer index兩個信息,其中低8位代表操作類型,高8位代表pointer index 。

2.pointer信息

  1. 通過getPointerCount()方法獲取此事件產生時pointer的個數,它一定是大于等于1的。例如有兩個手指接觸在屏幕上,則getPointerCount()為2。
  2. 通過getPointerId(int pointerIndex)獲取pointerIndex對應的pointer id。
  3. 通過findPointerIndex(int pointerId)獲取pointerId對應的pointer index。
  4. 通過getX(int pointerIndex),getY(int pointerIndex)方法來獲取此事件產生時pointerIndex對應的pointer在屏幕上的相對位置。
  5. 通過getRawX(),getRawY()方法來獲取此事件產生時pointerIndex對應的pointer在屏幕上的絕對位置。不帶參數的重載方法表示獲取pointerIndex為0的pointer在屏幕上的位置。

除此之外,還有getToolMajor(),getToolMinor(),getTouchMajor(),getTouchMinor(),getOrientation()等方法獲取pointer的區域大小,方向等信息。由于實際使用的較少,這里就不做介紹了。

3.操作時間

可以通過MotionEvent類的getEventTime()方法來獲取此事件產生的時間。

4.事件序列的歷史數據

在MotionEvent對象中還會保存其所在的事件序列的一些歷史事件的信息,可以通過getHistorySize()獲取歷史事件記錄的條數,通過一系列的getHistoricalXXX()方法獲取歷史事件的信息。由于ACTION_DOWN 是一個事件序列的開始,所以ACTION_DOWN對應的事件對象中是不會有歷史事件記錄的,在這之后的事件對應的MotionEvent對象中會有0到多個的歷史事件信息的記錄,具體記錄的個數并不固定,總的數量也不會太多。

在上述信息中,使用比較多的是前兩條,也就是事件的類型和事件產生時pointer的相關信息。

如有疑問請留言或者到本站社區交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 桂东县| 遵义县| 大悟县| 当雄县| 手机| 临武县| 西盟| 乾安县| 开原市| 屏东县| 秦皇岛市| 张家界市| 屏东市| 揭阳市| 克山县| 沙田区| 南川市| 仙游县| 墨竹工卡县| 浪卡子县| 烟台市| 思南县| 蓬溪县| 环江| 嵊州市| 通河县| 石城县| 洪泽县| 天津市| 治多县| 临桂县| 仪征市| 准格尔旗| 黄平县| 正阳县| 曲阜市| 阿拉善右旗| 凌海市| 桓仁| 鄯善县| 夹江县|