Android - requestDisallowInterceptTouchEvent() 阻止父层的View截获touch事件(事件处理机制)

研究这个方法以前,首先让咱们回顾一下View的onTouchEvent()以及onInterceptTouchEvent()的详细解释 
(1)onTouchEvent()spa

当手指触摸到屏幕时,系统就会调用相应View的onTouchEvent,并传入一系列的action。
当有多个层级的View时,在父层级容许的状况下,这个action会一直向下传递直到遇到最深层的View。
因此touch事件最早调用的是最底层View的onTouchEent,
若是View的onTouchEvent接收到某个touch action并做了相应处理,最后有两种返回方式return true和return false;
return true会告诉系统当前的View须要处理此次的touch事件,之后的系统发出的ACTION_MOVE,ACTION_UP仍是须要继续监听并接收的,
并且此次的action已经被处理掉了,父层的View是不可能触发onTouchEvent了。
因此每个action最多只能有一个onTouchEvent接口返回true。
若是return false,便会通知系统,当前View不关心这一次的touch事件,此时这个action会传向父级,调用父级View的onTouchEvent。
可是这一次的touch事件以后发出的任何action,该View都不会再接受,onTouchEvent在这一次的touch事件中不再会触发,
也就是说一旦View返回false,那么以后的ACTION_MOVE,ACTION_UP等ACTION就不会在传入这个View,可是下一次touch事件的action仍是会传进来的。

(2)onInterceptTouchEvent()接口

前面说了底层的View可以接收到此次的事件有一个前提条件:在父层级容许的状况下。
假设不改变父层级的dispatch方法,在系统调用底层onTouchEvent以前会先调用父View的onInterceptTouchEvent方法判断,
父层View是否是要截获本次touch事件以后的action。
若是onInterceptTouchEvent返回true,那么本次touch事件以后的全部action都不会再向深层的View传递,通通都会传给本层View的onTouchEvent,
就是说父层已经截获了此次touch事件,以后的action也没必要询问onInterceptTouchEvent,
在此次的touch事件以后发出的action时onInterceptTouchEvent不会再次调用,直到下一次touch事件的来临。
若是onInterceptTouchEvent返回false,那么本次action将发送给更深层的View,
而且以后的每一次action都会询问父层的onInterceptTouchEvent需不须要截获本次touch事件。
只有ViewGroup才有onInterceptTouchEvent方法,由于一个普通的View确定是位于最深层的View,
touch事件可以传到这里已是最后一站了,确定会调用View的onTouchEvent。

(3)requestDisallowInterceptTouchEvent()事件

对于底层的View来讲,有一种方法能够阻止父层的View截获touch事件,就是调用
getParent().requestDisallowInterceptTouchEvent(true);
一旦底层View收到touch的action后调用这个方法那么父层View就不会再调用onInterceptTouchEvent了,也没法截获之后的action

public boolean dispatchTouchEvent(MotionEvent ev) {   
    getParent().requestDisallowInterceptTouchEvent(true);  
    return super.dispatchTouchEvent(ev);    
}  get

public boolean onTouch(View v, MotionEvent event) {  
   switch (event.getAction()) {  
   case MotionEvent.ACTION_MOVE:   
       pager.requestDisallowInterceptTouchEvent(true);  
       break;  
   case MotionEvent.ACTION_UP:  
   case MotionEvent.ACTION_CANCEL:  
       pager.requestDisallowInterceptTouchEvent(false);  
       break;  
   }  
}  
 it

相关文章
相关标签/搜索