前言
這篇不探討畫面,探討 ViewGroup
裡面的一個細節 —InterceptTouchEvent
。
在 ViewGroup
裡面,因為一個 Group 裡面可能還會有子 group
以及子 view
,當去點擊子 group 的時候,同時其實也有觸碰到 parent,所以必須要另外再處理,可以看看下面的例子
失敗的例子
從這個例子可以看到,當我滑動 Image
的時候,照理講,應該這個 TouchEvent
必須作用在這個 image
就好,不應該作用到後面的 ViewPager
,但是為什麼會發生這種事情呢?
概念講解
根據官方文件(連結) 來看,他講到 ViewGroup
必須特別注意子 group 的觸發情形,在所有對子 view 做 touch 的事件時,都其實會先進 parent group 的 onInterceptTouchEvent
那關,之後才會進到子的 TouchEventListener
。所以說,看似手指只按在這張圖,實質也有進到了外面的 PageView
,當滑動這張圖的時候,自然而然的也會滑到後面那個部分,簡單來講,要接觸到小孩子,都會先被小孩子的父母攔截一次。
這邊如果想要只作用在特定的子 view,而不希望被外面的 group 影響的話,有兩個做法,一個是透過繼承 ViewPager
去寫一個 class,override
裡面的onInterceptTouchEvent
使他回傳 false
。這樣在手指觸碰到的時候就回傳 false
,不去理會接下來滑動的狀態。另一個作法如下解釋
禁止被 parent 擷取 touchEvent
view.imgView.setOnTouchListener { view, motionEvent ->
when(motionEvent.action){
MotionEvent.ACTION_DOWN ->view.parent.requestDisallowInterceptTouchEvent(true)
MotionEvent.ACTION_UP ->view.parent.requestDisallowInterceptTouchEvent(false)
}
return@setOnTouchListener true
}
每次點擊那張圖的時候,都會進到 ViewPager
,那麼有沒有禁止被該元件的 parent 擷取 touchEvent 的方法呢?答案是有的,使用上面的 requestDisallowInterceptTouchEvent
就可以達到這個效果。
當我的手指按下的時候,我不希望被我的 parent 擷取資訊,所以就先請他 "不准干擾別人!",這樣一來,當手指按下之後, parent 就不會去擷取他的孩子的 touchEvent,所以我現在的 slide Event 就會完全作用在這張圖(子 view )上面,當手放開之後,恢復了 parent ,這時 parent 又可以照原樣的去 intercept 他的子 view 啦~參考連結
由此可以看到,進到子 viewGroup A 的時候,都會被他的 parent 給 interceptTouch 擷取過一次,為了不去被該 parent 改擷取,使用上面 code 的方法就可以解決這件事情囉。