Android中dispatchTouchEvent, onInterceptTouchEvent, onTouchEvent的理解
【轉】http://blog.csdn.net/guitk/article/details/7057155
onInterceptTouchEvent用于改變事件的傳遞方向。決定傳遞方向的是返回值,返回為false時事件會傳遞給子控件,返回值為true時事件會傳遞給當前控件的onTouchEvent(),這就是所謂的Intercept(攔截)。
[tisa ps:正確的使用方法是,在此方法內僅判斷事件是否需要攔截,然后返回。即便需要攔截也應該直接返回true,然后由onTouchEvent方法進行處理。]
??? onTouchEvent用于處理事件,返回值決定當前控件是否消費(consume)了這個事件。尤其對于ACTION_DOWN事件,返回true,表示我想要處理后續事件;返回false,表示不關心此事件,并返回由父類進行處理。
??? 可能你要問是否消費了又區別嗎,反正我已經針對事件編寫了處理代碼?答案是有區別!比如ACTION_MOVE或者ACTION_UP發生的前提是一定曾經發生了ACTION_DOWN,如果你沒有消費ACTION_DOWN,那么系統會認為ACTION_DOWN沒有發生過,所以ACTION_MOVE或者ACTION_UP就不能被捕獲。
在沒有重寫onInterceptTouchEvent()和onTouchEvent()的情況下(他們的返回值都是false),?對上面這個布局,MotionEvent事件的傳遞順序如下:
當某個控件的onInterceptTouchEvent()返回值為true時,就會發生截斷,事件被傳到當前控件的onTouchEvent()。如我們將LayoutView2的onInterceptTouchEvent()返回值為true,則傳遞流程變成:
?如果我們同時將LayoutView2的onInterceptTouchEvent()和onTouchEvent()設置成true,那么LayoutView2將消費被傳遞的事件,同時后續事件(如跟著ACTION_DOWN的ACTION_MOVE或者ACTION_UP)會直接傳給LayoutView2的onTouchEvent(),不傳給其他任何控件的任何函數。同時傳遞給子空間一個ACTION_CANCEL事件。傳遞流程變成(圖中沒有畫出ACTION_CANCEL事件):
?? ? ? ??
[tisa ps:總體來看,?onInterceptTouchEvent是自rootview向下傳遞, onTouchEvent正好相反。]
?
【轉】http://blog.csdn.net/cyp331203/article/details/41039635
?
Android中觸摸事件傳遞過程中最重要的是dispatchTouchEvent()、onInterceptTouchEvent()和onTouchEvent()方法。這個是困擾初學者的問題之一,我開始也是。這里記錄一下dispatchTouchEvent()、onInterceptTouchEvent()和onTouchEvent()的處理過程,以供記憶。
?
? ? dispatchTouchEvent是處理觸摸事件分發,事件(多數情況)是從Activity的dispatchTouchEvent開始的。執行
super.dispatchTouchEvent(ev),事件向下分發。
? ??onInterceptTouchEvent是ViewGroup提供的方法,默認返回false,返回true表示攔截。
? ??onTouchEvent是View中提供的方法,ViewGroup也有這個方法,view中不提供onInterceptTouchEvent。view中默認返回true,表示消費了這個事件。
?
View里,有兩個回調函數?:
?
[java]?view plaincopy?
?
ViewGroup里,有三個回調函數?:
?
[java]?view plaincopy?
?
在Activity里,有兩個回調函數?:
?
?
[java]?view plaincopy?
? ? Android中默認情況下事件傳遞是由最終的view的接收到,傳遞過程是從父布局到子布局,也就是從Activity到ViewGroup到View的過程,默認情況,ViewGroup起到的是透傳作用。Android中事件傳遞過程(按箭頭方向)如下圖,圖片來自[qiushuiqifei],謝謝[qiushuiqifei]整理。
?
??
? ? 觸摸事件是一連串ACTION_DOWN,ACTION_MOVE..MOVE…MOVE、最后ACTION_UP,觸摸事件還有ACTION_CANCEL事件。事件都是從ACTION_DOWN開始的,Activity的dispatchTouchEvent()首先接收到ACTION_DOWN,執行super.dispatchTouchEvent(ev),事件向下分發。
? ? dispatchTouchEvent()返回true,后續事件(ACTION_MOVE、ACTION_UP)會再傳遞,如果返回false,dispatchTouchEvent()就接收不到ACTION_UP、ACTION_MOVE。
?
?
下面的幾張圖參考自[eoe]
?
?
?
? ? ? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖1.ACTION_DOWN都沒被消費
?
?
?
?
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖2-1.ACTION_DOWN被View消費了
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?圖2-2.后續ACTION_MOVE和UP在不被攔截的情況下都會去找VIEW
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖3.后續的被攔截了
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?圖4ACTION_DOWN一開始就被攔截
?
?
android中的Touch事件都是從ACTION_DOWN開始的:
?
單手指操作:ACTION_DOWN---ACTION_MOVE----ACTION_UP
多手指操作:ACTION_DOWN---ACTION_POINTER_DOWN---ACTION_MOVE--ACTION_POINTER_UP---ACTION_UP.
?
【轉】http://blog.csdn.net/stzy00/article/details/40378533
在布局文件里,假設有3層 , 一層是button, textview等常見組件, 二層是嵌套的RelativeLayout, 三層是LinearLayout, 而一個觸摸屏幕的事件無非就是ACTION_DOWN, ACTION_MOVE, ACTION_UP. ?而手指從按下到松開離開屏幕, 其實事件分發的傳遞已經經過了這三層. 這里說下它的處理過程, 也算是鞏固記憶了.
?
首先,?dispatchTouchEvent(),onInterceptTouchEvent()和onTouchEvent() 這三個方法在每個view都會有, 而無論button,textview還是LinearLayout, RelativeLayout它們最終都繼承于View, ViewGroup,因此 這三個方法它們各自都有.?dispatchTouchEvent() 負責觸摸屏幕事件(down - move - up)的分發,?onInterceptTouchEvent()負責事件中的攔截,?onTouchEvent()就是事件的處理了.
接著,來說說這三層中各自的三個方法如何參與了這個過程:
從Activity開始, 接收到手指按下屏幕的事件,即ACTION_DOWN, 最先到達LinearLayout, LinearLayout調用dispatchTouchEvent(), dispatchTouchEvent()一般不會用于重寫, 它會自動分發給onInterceptTouchEvent(),如果onInterceptTouchEvent()的ACTION_DOWN 里面返回fasle就代表自己不處理這個事件,而是交給下一個去處理它, 于是繼續把這個事件分發到下一層RelativeLayout, 同理RelativeLayout中如果onInterceptTouchEvent()的ACTION_DOWN依舊返回false的話, 就到達TextView這里. 當TextView的onInterceptTouchEvent())中返回true了 , 就代表由自己來處理這個事件, 也相當于攔截了這個事件.當處理完,返回true就將事件的處理結果逆向提交到Activity中, 告訴Activity自己處理好了. 然后接下來的ACTION_MOVE和ACTION_UP這兩個事件才會繼續傳到TextView中并得到處理. ? ?
假如,剛開始的ACTION_DOWN在RelativeLayout就被處理掉 (即 RelativeLayout中的onInterceptTouchEvent()返回true,交由自己的onTouchEvent()去處理, 下層的TextView就無法參與這次觸摸事件的傳遞分發, 后面的ACTION_MOVE和ACTION_UP, TextView也就無法得到傳遞).所以如果要攔截某一個TOUCH動作,就在onInterceptTouchEvent()動手吧(嘻嘻,這樣說好理解一些嘛.) 只要攔截了ACTION_DOWN,后面的MOVE和UP事件都不會往下傳遞, 而只攔截MOVE事件, 則UP事件不再往下傳遞. 但無論是哪個View處理了這次的觸摸事件, 其最后處理的結果都必須會逆向地提交到Activity中, 這樣用戶觸摸屏幕的動作才會得到對應的反饋.
轉載于:https://www.cnblogs.com/clong2010/p/4541217.html
總結
以上是生活随笔為你收集整理的Android中dispatchTouchEvent, onInterceptTouchEvent, onTouchEvent的理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU 5239 上海大都会 D题(线段
- 下一篇: 文件上传画水印