【知识梳理1】Android触摸事件机制
前言
隨著科學(xué)技術(shù)的發(fā)展,智能手機(jī)早已成為我們當(dāng)代人身邊不可缺少的“伙伴”之中的一個(gè),堪比對(duì)象女友。每天我們對(duì)著手機(jī)反復(fù)的做著點(diǎn)擊、滑動(dòng)操作,而手機(jī)則隨著我們的操作給我們展示她的精彩。
…
廢話(huà)到此結(jié)束。
看到這里,即使不是作為移動(dòng)端碼農(nóng)的你也應(yīng)該知道觸摸事件對(duì)手機(jī)(經(jīng)典鍵盤(pán)機(jī)除外)的重要性了。
什么是觸摸事件
顧名思義。就是觸摸手機(jī)屏幕后產(chǎn)生的事件。這時(shí)候請(qǐng)你拿出手機(jī)。點(diǎn)擊屏幕中的某個(gè)按鈕(不要松手),移動(dòng)一段距離。松手。
這個(gè)過(guò)程通常會(huì)產(chǎn)生例如以下幾個(gè)事件:
Android為我們封裝好了一個(gè)觸摸事件類(lèi)MotionEvent,上述的三個(gè)過(guò)程分別相應(yīng)著MotionEvent中的MotionEvent.ACTION_DOWN、MotionEvent.ACTION_MOVE、MotionEvent.ACTION_UP事件類(lèi)型,我們能夠以此來(lái)實(shí)現(xiàn)不同的邏輯,即事件的分發(fā)處理。所謂觸摸事件的分發(fā),實(shí)際上能夠理解為MotionEvent事件的分發(fā)過(guò)程,即當(dāng)一個(gè)MotionEvent產(chǎn)生了之后,系統(tǒng)須要把這個(gè)事件傳遞給一個(gè)詳細(xì)的View,而這個(gè)傳遞的過(guò)程就是分發(fā)過(guò)程。
事件三劍客
一般事件的分發(fā)過(guò)程是由事件三劍客(方法)來(lái)共同完畢的。
/*** 劍客一:用于事件的分發(fā)*/ public boolean dispathTouchEvent(MotionEvent ev)/*** 劍客二:在劍客一中被調(diào)用,用于事件的攔截*/ public boolean onInterceptTouchEvent(MotionEvent ev)/*** 劍客三:在劍客一中被調(diào)用。處理點(diǎn)擊事件。true:消耗了當(dāng)前事件 false:當(dāng)前view無(wú)* 法再次接收事件*/ public boolean onTouchEvent()(MotionEvent ev)三劍客的關(guān)系例如以下圖所看到的(以Activity的dispathTouchEvent為例)
分析可知:
1. 觸摸事件ev類(lèi)收到點(diǎn)擊的ACTION,會(huì)回調(diào)onUserInteraction方法,一般項(xiàng)目中我們把一些須要用戶(hù)開(kāi)始觸摸時(shí)就須要執(zhí)行的任務(wù)代碼放在這里。
2. 接下來(lái)觸摸事件ev會(huì)傳遞給Activity窗體綁定的根視圖rootView(View/ViewGroup)。如果根視圖也有子視圖。事件ev會(huì)一級(jí)一級(jí)的分發(fā)下去,如果在這個(gè)過(guò)程中ev被消耗了,事件就此結(jié)束分發(fā),否則進(jìn)入步奏3。
3. 全部的視圖布局都沒(méi)有消耗掉ev事件。就會(huì)調(diào)用Activity的onTouchEvent()方法。以下會(huì)詳細(xì)講訴。
Android界面簡(jiǎn)析
在詳細(xì)講訴前,我們先來(lái)了解下的android的界面架構(gòu)。如果說(shuō)手機(jī)是一個(gè)學(xué)校,那么手機(jī)中的每一個(gè)APP(應(yīng)用)都是學(xué)校里的一道道獨(dú)特風(fēng)景,正是它們,構(gòu)成了學(xué)校的魅力。而每一個(gè)APP都是由一個(gè)個(gè)Activity組成的。
還是在說(shuō)廢話(huà)…
例如以下圖所看到的,我們清晰的看到每一個(gè)Activity都會(huì)包括一個(gè)Window對(duì)象。而window對(duì)象通常由PhoneWindow來(lái)實(shí)現(xiàn)。
PhoneWindow將一個(gè)DecorView設(shè)置為整個(gè)應(yīng)用窗體的根View。它將屏幕分成兩部分。一個(gè)是TitleView。還有一個(gè)是ContentView(也就是大家熟悉的ContentView布局)。
ContentView是一個(gè)ID為content的FrameLayout,而我們一直寫(xiě)的activity_xx.xml布局就是設(shè)置在這樣一個(gè)FrameLayout里。
DecorView將要顯示的詳細(xì)內(nèi)容呈如今了PhoneWindow上。這里面的全部View的監(jiān)聽(tīng)事件(點(diǎn)擊、滑動(dòng)等操作)都通過(guò)一個(gè)名為WindowManagerService來(lái)進(jìn)行接收(詳細(xì)可看深入理解android卷三),并通過(guò)Activity來(lái)回調(diào)相應(yīng)的監(jiān)聽(tīng)。
為了讓大家更好的理解。我們來(lái)寫(xiě)一個(gè)小demo例如以下
執(zhí)行結(jié)果如圖
小場(chǎng)景。見(jiàn)真理
場(chǎng)景一
我們寫(xiě)一個(gè)最簡(jiǎn)單的demo例如以下
執(zhí)行程序,點(diǎn)擊button,看到log輸出例如以下:
改動(dòng)dispathTouchEvent,直接return false。
執(zhí)行程序,點(diǎn)擊button,是不是看到控制臺(tái)什么都沒(méi)有輸出。可見(jiàn)事件傳遞到activity的根視圖就被結(jié)束分發(fā)了。以下已場(chǎng)景二來(lái)詳細(xì)探究下這個(gè)過(guò)程。
場(chǎng)景二
假如在大學(xué)中。學(xué)校交給了數(shù)學(xué)老師一個(gè)任務(wù)。老師講這項(xiàng)任務(wù)布置給了女班長(zhǎng)。而女班長(zhǎng)又將這個(gè)任務(wù)交給了帥氣的我。我千辛萬(wàn)苦的將這個(gè)任務(wù)完畢了,然后交給了女班長(zhǎng),女班長(zhǎng)認(rèn)為完畢的不錯(cuò),夸了帥氣的我?guī)拙?#xff08;暗戀上了),然后將任務(wù)提交給了老師,老師看了下也認(rèn)為完畢的不錯(cuò),就把任務(wù)提交給學(xué)校了。
根據(jù)上面的場(chǎng)景,我們?cè)O(shè)計(jì)一個(gè)場(chǎng)景實(shí)比例如以下
布局層次例如以下圖所看到的
TeacherViewGroup和MonitressViewGroup代碼例如以下。重寫(xiě)了三劍客方法
HandsomeMyView代碼例如以下,view是沒(méi)有劍客2(方法)onInterceptTouchEvent()的
點(diǎn)擊帥氣的我能夠看見(jiàn)log打印例如以下
能夠看見(jiàn)一般事件都有兩個(gè)過(guò)程
- 傳遞過(guò)程 : 老師(TeacherViewGroup)——>女班長(zhǎng)(MonitressViewGroup)——>帥氣的我(HandsomeMyView)
- 處理過(guò)程 : 帥氣的我(HandsomeMyView)——>女班長(zhǎng)(MonitressViewGroup)——>老師(TeacherViewGroup)
傳遞的過(guò)程方法:劍客1(dispatchTouchEvent)、劍客2(onInterceptTouchEvent)
處理的過(guò)程方法:劍客3(onTouchEvent)
為了讓大家更好的理解。整理視圖例如以下:
從中我們看出觸摸事件ev會(huì)依照子View增加ViewGroup先后順序相反的順序。依次有機(jī)會(huì)去消費(fèi)此觸摸事件ev。即最后增加的最先有機(jī)會(huì)消費(fèi)此觸摸事件(消費(fèi)的前提是,觸摸點(diǎn)在這個(gè)子View的視圖范圍之內(nèi))。簡(jiǎn)而言之,傳遞由外向內(nèi),消費(fèi)(處理)由內(nèi)向外。
在前面的事件三劍客中細(xì)心的同學(xué)會(huì)發(fā)現(xiàn),他們的返回值都是boolean類(lèi)型,那么true和false分別代表什么意義呢?
在這里我先告訴大家結(jié)論,然后在驗(yàn)證這個(gè)結(jié)論:
dispatchTouchEvent()和onInterceptTouchEvent()
- 返回true表示事件被攔截。不繼續(xù)。
- 返回false表示事件不被攔截,繼續(xù)下一步流程。
onTouchEvent()
- 返回true表示事件被處理了,不用傳遞給上一級(jí)視圖;
- 返回false表示事件交給上一級(jí)視圖處理;
初始情況下他們的默認(rèn)返回值都為false。
攔截onInterceptTouchEvent()
如果女班長(zhǎng)暗戀帥氣的我,自己偷偷幫我完畢了任務(wù),這時(shí)候事件就被女班長(zhǎng)(MonitressViewGroup)的onInterceptTouchEvent()方法攔截了,即MonitressViewGroup的onInterceptTouchEvent()返回ture,此時(shí)Log輸出例如以下
整理視圖例如以下:
相同的,也能夠如果老師人比較好,不忍心麻煩學(xué)生。自己處理了。這個(gè)過(guò)程相似女班好處理過(guò)程。
到這里,我想大家對(duì)事件的分發(fā)、攔截已經(jīng)有一個(gè)比較清晰的認(rèn)識(shí)了。接下來(lái)我們來(lái)看下事件的處理。
處理onTouchEvent()
我們處理完任務(wù)后是須要將完畢結(jié)果匯報(bào)給上級(jí)的。也就是帥氣的我須要向我親愛(ài)的女班長(zhǎng)匯報(bào)結(jié)果。班長(zhǎng)向老師匯報(bào)結(jié)果。如果我不能按時(shí)完畢任務(wù)。沒(méi)將任務(wù)結(jié)果匯報(bào)給女班長(zhǎng)。也就是HandsomeMyView的onTouchEvent()方法返回true(事件被處理了。不用返回給上級(jí)),此時(shí)Log輸出例如以下。女班長(zhǎng)和老師不用繼續(xù)處理事件了
整理視圖例如以下:
相同的,女班長(zhǎng)和老師也能夠不像他們各自的上級(jí)匯報(bào)。過(guò)程相似帥氣的我(HandsomeMyView)。
Ref
…
轉(zhuǎn)載于:https://www.cnblogs.com/llguanli/p/8515389.html
總結(jié)
以上是生活随笔為你收集整理的【知识梳理1】Android触摸事件机制的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 从xtrabackup备份恢复单表【转】
- 下一篇: 在Android项目中使用AspectJ