1.? 怎么做到當路徑上有一個ViewGroup攔截了Down事件之后,后續的move , up等事件就只交給它來處理,? 而不會再繼續往下走了?
2. ?個中主流控件, 包括FrameLayout, RelatvieLayout, LinearLayout, 等都是如何實現其 onTouchEvent, onInterceptTouchEvent, dispatchTouchEvent方法的.?"
有什么共性? ? 有什么區別?
-----上面提到的三個布局都沒有實現任何一個方法, 都是集成的ViewGroup中的邏輯, ? 而他們的直接父類, ViewGroup 也只實現了onInterceptTouchEvent() 和dispatchTouchEvent()
并且onInterceptTouchEvent()中基本上就是返回false,( 除了是鼠標拖動滾動條的事件).
所以基本上, 分析的重點就在View.java和ViewGroup.java中的dispatchTouchEvent()方法.
ScrollView ?實現了自己的onInterceptTouchEvent()onTouchEvent() ? ?注意ScrollView 繼承了FrameLayout, 只支持豎向
onInterceptTouchEvent() 注釋說的明白: 我們只關心當前是不是正在被滑動(dragging).
從實際效果上, 不管承載的控件們是否攔截或者處理了touchEvent, ScrollView本身都是會相應滑動的.
只要是move事件, 判斷出滑動距離超過touchSlop之后, ?就認為是在dragging. 那么就會返回true, 后續的事件都會自行處理.并且從這個返回true的事件開始, 會給子控件一個cancel.
再重申一遍重點:
只有在move事件中, 并且當累計滑動距離(初始位置是在down時記錄的)已經超過了touchSlop了, ?那么就會對子控件發出cancel事件, 對父控件調用:requestDisallowInterceptTouchEvent(true), 通知父親控件, 不要瞎摻和了.
上面說的的對子控件發出cancel事件是怎么做到的? ?在這個事件的處理流程上, dispatchTouchEvent()中, 先調用自身的onInterceptTouchEvent()判斷自身是否攔截, 如上面分析, 如果攔截, 那么下面的intercepted變量為true, 所以接下來調用dispatchTransformedTouchEvent()時, cancelChild參數為true, 里面會生成cancel事件, 并交給子控件處理. ?并且有一點注意:對于這個子控件, 處理完cancel事件之后, 后續的move, up事件也不會再交給它處理了. ? 中斷了, ?跟它沒關系了,
問題: 那么上面說的這點又是怎么做到的呢: ?怎么才做到cancel之后, 后續的事件都不給這個子控件了?
上面這個段代碼中高亮選中部分, ?會在子控件處理完cancel之后, 把mFirstTouchTarget置為null. 因為對于ScrollView, 只有一個子控件, 所以next為null.
mFirstTouchTarget變成了null, 那下一次進入dispatchTouchEvent()后, 處理就簡單多了, 見下面代碼段:
對于之后的move事件, 并且mFirstTouchTarget已經為null, ?直接設置intercepted為true. ? 同時后面的流程也就不再調用子控件的dispatchTouchEvent()
AbsListView 實現了自己的onInterceptTouchEvent()onTouchEvent()
----------未完