研究这个方法以前,首先让咱们回顾一下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