《android高級進階》學習筆記(一)

《android高級進階》學習筆記(一)

1.android觸摸事件傳遞機制
1.1 在android系統中,擁有事件傳遞處理能力的類有以下三種:

  • Activity:擁有dispatchTouchEvent和onTouchEvent兩個方法;
  • View:擁有dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent三個方法;
  • ViewGroup:擁有dispatchTouchEvent和onTouchEvent兩個方法。

1.2觸摸事件的類型
事件的類型主要有三種:

  • ACTION_DOWN:按下操作,一個按下操作標誌着一次觸摸事件的開始;
  • ACTION_MOVE:按壓屏幕後,在鬆開之前,如果移動距離超過一定的閾值,判定爲ACTION_MOVE操作,一般情況下,手指的輕微移動都會觸發一系列的移動事件;
  • ACTION_UP:手指離開屏幕的操作,一次擡起操作標誌着一次觸摸事件的結束。

    一次觸摸事件中,ACTION_DOWN和ACTION_UP兩個事件類型是必需的,ACTION_MOVE視情況而定。

1.3事件傳遞的三個階段
一次完整的事件傳遞主要包括三個階段,分別是事件的分發、攔截和消費。

  • 分發(dispatch):事件的分發對應着dispatchTouchEvent方法,在android系統中,所有的觸摸事件都是通過此方法來分發的,方法原型如下:
public boolean dispatchTouchEvent(MotionEvent ev)

在此方法中,根據當前視圖的具體實現邏輯來決定是直接消費此事件還是將此事件分發給子視圖處理,返回值爲true,表示事件被當前視圖消費掉,不再分發事件;返回值爲super.dispatchTouchEvent 表示分發事件給子視圖。如果當前視圖是ViewGroup及其子類,則會調用onInterceptTouchEvent方法是否攔截該事件。

  • 攔截(intercept):事件的攔截對應onInterceptTouchEvent方法,此方法只在ViewGroup及其子類中才存在,在View和Activity中是不存在的。方法的原型如下:
public boolean onInterceptTouchEvent(MotionEvent ev)

此方法通過返回的布爾值來決定是否攔截對應的事件,返回true表示攔截此事件,不繼續分發給子視圖,同時交給自身的onTouchEvent方法進行消費;返回false或者super.onInterceptTouchEvent 表示不對事件進行攔截,繼續傳遞給子視圖。

  • 消費(Consume):事件的消費對應着onTouchEvent方法,方法原型如下
public boolean onTouchEvent(MotionEvent event)

此方法返回值爲true 表示當前視圖可以處理對應的事件,事件將不會向上傳遞給父視圖;返回值爲false 表示當前視圖不處理該事件,事件會被傳遞給父視圖的onTouchEvent方法進行處理。

1.4View的事件傳遞機制
以View的ACTION_DOWN事件爲例,流程圖如下:

Created with Raphaël 2.1.2用戶點擊屏幕ACTION_DOWN事件執行父視圖的dispatchTouchEvent返回super?執行view的dispatchTouchEvent返回super?執行父視圖的onTouch返回true(yes)或者false(no)?不再繼續分發ACTION_DOWN事件,同時不會調用父視圖的onClick方法執行view的onTouchEvent返回super?ACTION_DOWN傳遞完成 返回true(yes)或者false(no)?執行父視圖的onTouchEvent返回true(yes)或者false(no)?yesnoyesnoyesnoyesnoyesnoyesno

從上面流程圖總結:

  • 觸摸事件的傳遞流程是從dispatchTouchEvent開始的,如果默認返回父類的同名函數,則事件會依照嵌套層次從外層向內層傳遞,達到最內層的View時,由View的onTouchEvent方法處理,g該方法若消費此事件,則返回true,否則返回false,此時事件會重新向外層傳遞,並有外層View的onT方法進行處理,以此類推。
  • 如果事件在向內層傳遞過程中由於人爲干預,事件處理函數返回true,則事件會提前消費掉,內層View將不會收到該事件。
  • View控件的事件觸發順序是先執行onTouch方法,在最後才執行onClick方法。如果onTounch返回true。則事件終止傳遞,最後也不會調用onClick方法;如果onTouch返回false,則事件繼續傳遞。

1.5 ViewGroup的事件傳遞機制
ViewGroup擁有dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent三個方法。
事件傳遞流程圖如下:

Created with Raphaël 2.1.2用戶點擊屏幕ACTION_DOWN事件執行Activity的dispatchTouchEvent返回super?執行ViewGroup的dispatchTouchEvent返回super?執行ViewGroup的onInterceptTouchEvent返回super?執行View的dispatchTouchEvent返回super?執行Activity的onTouch返回true(yes)或者false(no)?終止分發ACTION_DOWN事件同時不會調用Activity的onClick執行View的onTouchEvent返回super?ACTION_DOWN傳遞完成 返回true(yes)或者false(no)?執行Activity的onTouchEvent返回true(yes)或者false(no)?返回true(yes)或者false(no)?執行ViewGroup的onTouchEvent返回super?執行Activity的onTouchEvent返回true(yes)或者false(no)?yesnoyesnoyesnoyesnoyesnoyesnoyesnoyesnoyesnoyesyesno

從上面流程圖得出結論:

  • 觸摸事件的傳遞順序是由Activity到ViewGroup,再由ViewGroup遞歸傳遞給其子View;
  • ViewGroup通過onInterceptTouchEvent方法對事件進行攔截,該方法若返回true,則事件不會繼續傳遞給子View,若返回false或者super.onInterceptTouchEvent,則事件會繼續傳遞給子View。
  • 在子View中對事件進行消費後,ViewGroup將接受不到任何事件。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章