與手勢事件有關的方法
- dispatchTouchEvent():該方法將觸摸事件分發給相應的視圖或視圖組。
- onInterceptTouchEvent():該方法用于判斷是否需要攔截觸摸事件,如果需要攔截,則返回 true,否則返回 false。
- onTouchEvent():該方法用于處理觸摸事件,返回一個 boolean 類型的值,表示是否消費了該事件。
此外,與手勢事件有關的常見方法還包括:
- onTouch():在視圖上觸摸了屏幕時調用。
- onLongPress():在視圖上長按屏幕時調用。
- onDoubleTap():在視圖上雙擊屏幕時調用。
- onSingleTapUp():在視圖上單擊屏幕并且手指抬起時調用。
- onShowPress():在視圖上按下屏幕并且沒有松開時調用。
- onDown():在視圖上按下屏幕時調用。
- onUp():在視圖上抬起手指時調用。
- onScroll():在視圖上發生滾動時調用。
- onFling():在視圖上發生滑動時調用。
手勢事件的分發流程可以描述如下:
- 用戶在屏幕上進行觸摸操作,觸摸事件被Android系統捕獲。
- Android系統首先將觸摸事件傳遞給當前活動的窗口,即頂層的窗口。
- 窗口會將觸摸事件傳遞給當前顯示的頁面類(Activity、Fragment等)。
- 頁面類會根據觸摸事件的類型,將其分發給相應的容器類或控件類。
- 容器類(ViewGroup)會先接收到觸摸事件,它會遍歷其子視圖,并將觸摸事件傳遞給子視圖,直到找到合適的控件類。
- 控件類(Button、ImageView等)接收到觸摸事件后,會根據事件類型進行相應的處理。如果控件類設置了觸摸監聽器(OnTouchListener),則會調用監聽器中的回調方法。
- 如果沒有設置觸摸監聽器,控件類會判斷是否實現了手勢識別的接口(如OnGestureListener),如果實現了,則會調用相應的手勢回調方法。
- 如果觸摸事件沒有被任何控件類處理或消耗,那么事件將繼續向上層傳遞,直到被處理或到達頂層窗口。
- 如果觸摸事件最終沒有被處理,系統會執行默認的處理邏輯,例如滾動屏幕或執行點擊操作。
- 需要注意的是,觸摸事件的分發流程是按照視圖層次結構從上到下的順序進行的,即從窗口到頁面類、容器類和控件類。每個層次的組件都有機會處理觸摸事件,
如果事件被處理或消耗,則不會繼續向下傳遞。這樣可以實現觸摸事件的精確分發和響應。
手勢方法的執行者
對于Android觸摸事件中手勢方法的執行者,可以將其進一步細分為頁面類、容器類和控件類。
- 頁面類(Activity、Fragment等):在Android應用中,頁面類是最頂層的組件,負責顯示用戶界面和處理用戶交互。頁面類可以實現手勢識別的接口,并通過重寫相應的手勢回調方法來處理手勢事件。例如,可以在頁面類中實現OnGestureListener接口,重寫onFling()方法來處理滑動手勢。
- 容器類(ViewGroup):容器類是用于包含和管理其他視圖組件的容器。例如,LinearLayout、RelativeLayout等。容器類可以監聽并處理手勢事件,并傳遞給包含在其中的子視圖或控件。在容器類中,可以實現OnTouchListener接口或重寫onTouchEvent()方法來處理手勢事件。只有容器類可以調用onInterceptTouchEvent方法
- 控件類(Button、ImageView等):控件類是Android中內置的UI組件,用于展示特定功能或接收用戶輸入。控件類可以設置監聽器來處理手勢事件,例如設置OnTouchListener接口或實現GestureDetector.OnGestureListener接口。通過將手勢事件傳遞給控件類,可以實現對于具體控件的手勢操作響應。
綜上所述,頁面類是頂層的組件,負責整個頁面的顯示和交互處理;容器類是用于包含和管理其他視圖組件的容器,負責組織和布局;
控件類是用于展示特定功能或接收用戶輸入的UI組件,負責展示和響應用戶的交互操作。通過理解它們的功能和作用,可以區分頁面類、容器類和控件類。
對實際開發來說,把常見的幾種手勢流程的排列組合搞清楚
- 頁面類的手勢處理,它dispatchTouchEvent方法必須返回super.dispatchTouchEvent,如果不分發,頁面上的視圖就無法處理手勢,
至于頁面類的onTouchEvent方法,基本沒有什么作用。因為手勢動作要由具體視圖處理,頁面直接處理手勢沒有什么意義。所以,頁面類的手勢處理可以不用關心,直接略過,
- 控件類的手勢處理。它的dispatchTouchEvent方法沒有任何作用,因為控件下面沒有子視圖,無所謂分不分發。至于控件類的onTouchEvent方法,如果要進行手勢處理,就需要自定義一個控件,
重寫自定義類中的onTouchEvent方法;如果不想自定義控件,就直接調用控件對象的 setOnTouchListener方法,注冊一個觸摸監聽器OnTouchListener,并實現該監聽器的onTouch方法。
所以,控件類的手勢處理只需關心onTouchEvent方法。
- 容器類的手勢處理。這才是真正要深入了解的地方。容器類的dispatchTouchEvent與 onlnterceptTouchEvent方法都能決定是否將手勢交給子視圖處理。為了避免手勢響應沖突,
一般要重寫dispatchTouchEvent或者onlnterceptTouchEvent方法。這兩個方法的區別可以這么理解:前者是大領導,只管派發任務,不會自己做事情:后者是小領導,盡管有攔截的權利,
過也得自己做點事情,比如處理糾紛等。容器類的onTouchEvent方法近乎擺設,因為需要攔截的在前面已經攔截了,需要處理的在子視圖中已經處理了。
經過上面的詳細分析,常見的手勢處理方法有下面3個:
- 頁面類的dispatchTouchEvent方法:控制事件的分發,決定把手勢交給誰處理。
- 容器類的onlnterceptTouchEvent方法:控制事件的攔截,決定是否要把手勢交給子視圖處理。
- 控件類的onTouchEvent方法:進行手勢事件的具體處理
在Android中,點擊事件的傳遞順序通常是按照以下順序進行的:
- Activity:當用戶點擊一個應用程序的界面時,首先會觸發該Activity的onTouchEvent()方法。
- Window:在Activity的onTouchEvent()方法中,會通過窗口管理系統(Window Manager)將觸摸事件傳遞給當前窗口(Window)。當前窗口可以是Activity中的任意一個視圖(View)。
- View:在窗口中,觸摸事件會被傳遞給視圖層次結構(View Hierarchy),從頂層視圖開始,依次向下傳遞。每個視圖都會根據自己的需要進行處理,例如,點擊事件可能被傳遞給一個按鈕(Button)或者文本框(TextView)等。