android 事件处理机制之requestDisallowInterceptTouchEvent

当手指触摸到屏幕时,系统就会调用相应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仍是会传进来的。
    前面说了底层的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。
对于底层的View来讲,有一种方法能够阻止父层的View截获touch事件,就是调用getParent().requestDisallowInterceptTouchEvent(true);方法。一旦底层View收到touch的action后调用这个方法那么父层View就不会再调用onInterceptTouchEvent了,也没法截获之后的action。
用例子总结一下onInterceptTouchEvent和onTouchEvent的调用顺序:
假设最高层View叫OuterLayout,中间层View叫InnerLayout,最底层View叫MyVIew。调用顺序是这样的(假设各个函数返回的都是false)
OuterLayout.onInterceptTouchEvent->InnerLayout.onInterceptTouchEvent->MyView.onTouchEvent->InnerLayout.onTouchEvent->OuterLayout.onTouchEvent。java

 

[java]  view plain copy 在CODE上查看代码片 派生到个人代码片
 
  1. @Override    
  2.     public boolean dispatchTouchEvent(MotionEvent ev) {   
  3.         getParent().requestDisallowInterceptTouchEvent(true);  
  4.         return super.dispatchTouchEvent(ev);    
  5.     }  


这句话是告诉父view,个人事件本身处理ide

 

 

[java]  view plain copy 在CODE上查看代码片 派生到个人代码片
 
  1. public boolean onTouch(View v, MotionEvent event) {  
  2.      switch (event.getAction()) {  
  3.      case MotionEvent.ACTION_MOVE:   
  4.          pager.requestDisallowInterceptTouchEvent(true);  
  5.          break;  
  6.      case MotionEvent.ACTION_UP:  
  7.      case MotionEvent.ACTION_CANCEL:  
  8.          pager.requestDisallowInterceptTouchEvent(false);  
  9.          break;  
  10.      }  
  11. }  


也能够写成相似于上面那样,当用户按下的时候,咱们告诉父组件,不要拦截个人事件(这个时候子组件是能够正常响应事件的),拿起以后就会告诉父组件能够阻止。函数

 

转自:http://blog.csdn.net/chaihuasong/article/details/17499799spa

相关文章
相关标签/搜索