android 事件拦截机制总结

                                                                                                           事件拦截分析
    说明:  LayoutView1、LayoutView2是ViewGroup  MyTextView是View  “ * ” 标识代表了需要注意的点,完全决定了事件分发

                   View由外到里层级结构为:LayoutView1-->LayoutView2-->MyTextView
 
  ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    一、“最外层View事件处理”测试分析
     LayoutView1 
                 onInterceptTouchEvent() return false;     
                 onTouchEvent()          return true;                       *
     LayoutView2
                onInterceptTouchEvent() return false;
                onTouchEvent()          return false;
  MyTextView
      onTouchEvent()          return false;
    拦截条件:最外层LayoutView1 在ACTION_DOWN时return false;并且LayoutView1中onTouchEvent()return true;其余View的onInterceptTouchEvent()和onTouchEvent() 都 return false;
    执行动作:滑动屏幕
    运行结果:
              LayoutView1: onInterceptTouchEvent action:ACTION_DOWN
              LayoutView2: onInterceptTouchEvent action:ACTION_DOWN
              LayoutView2: onTouchEvent action:ACTION_DOWN
              LayoutView1: onTouchEvent action:ACTION_DOWN
              LayoutView1: onTouchEvent action:ACTION_MOVE
              LayoutView1: onTouchEvent action:ACTION_MOVE
              ...此处省略LayoutView1onTouchEvent action:ACTION_MOVE多个
             LayoutView1: onTouchEvent action:ACTION_MOVE
             LayoutView1: onTouchEvent action:ACTION_UP
    分析:
           因为LayoutView1是ViewGroup并且在onInterceptTouchEvent()的ACTION_DOWN时return false,所以当ACTION_DOWN
           动作进入后不进行事件拦截,则事件会传递到LayoutView2的onInterceptTouchEvent(),由于LayoutView2在onInterceptTouchEvent()
           方法中ACTION_DOWN时也return false,所以也不拦截事件,则继续下传,但是由于下一个是MyTextView是View没有拦截方法
            onInterceptTouchEvent(),则事件拦截结束。则执行LayoutView2的onTouchEvent()方法,由于LayoutView2的onTouchEvent()
           在ACTION_DOWN时return false,不进行事件处理,则不会继续执行LayoutView2的Move、up动作,则向父View的onTouchEvent()传递
           回传到LayoutView1的onTouchEvent(),因为在ACTION_DOWN时return true,则进行事件处理,继续执行Move、up动作,然后
           整个事件执行结束
    总结:在事件传递的过程中,如果”所有“的ViewGroup没有拦截事件,则最终会传递到最里层的ViewGroup的OnTouchEvent()如果没有返回true
               进行这次的事件处理,则一直会向父View的OnTouchEvent()以此类推传递,知道遇见OnTouchEvent()return true,进行事件
               处理后,事件结束,等待下次传递。如果一直没有OnTouchEvent() return true,则传递到最外面,OnTouchEvent()事件结束。
    备注:值得注意的是LayoutView1的onInterceptTouchEvent()的ACTION_DOWN时return false后,就不再执行其Move、up了,因为
               ACTION_DOWN以后return false”系统“就认为LayoutView1不会拦截事件了,所以ACTION_MOVE、ACTION_UP就没必要传入了
               而是把动作直接传递给了OnTouchEvent() return true的View
 
  ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     二、“第二层View事件处理”测试分析
     LayoutView1 
                   onInterceptTouchEvent() return false;    
                   onTouchEvent()          return true;                        *

     LayoutView2
                   onInterceptTouchEvent() return false;
                   onTouchEvent()          return true;                        *
  MyTextView
                  onTouchEvent()          return false;
    执行动作:滑动屏幕
    运行结果:
                    LayoutView1: onInterceptTouchEvent action:ACTION_DOWN
                   LayoutView2: onInterceptTouchEvent action:ACTION_DOWN
                   LayoutView2: onTouchEvent action:ACTION_DOWN
                   LayoutView1: onInterceptTouchEvent action:ACTION_MOVE
                   LayoutView2: onTouchEvent action:ACTION_MOVE
                   ...此处省略N多个:LayoutView1: onInterceptTouchEvent action:ACTION_MOVE  LayoutView2: onTouchEvent action:ACTION_MOVE
                 LayoutView1: onInterceptTouchEvent action:ACTION_MOVE
                 LayoutView2: onTouchEvent action:ACTION_MOVE
                 LayoutView1: onInterceptTouchEvent action:ACTION_UP
                 LayoutView2: onTouchEvent action:ACTION_UP
    分析:首先和第一个测试结果进行分析,相同点:测试1的最后一条日志LayoutView1: onTouchEvent action:ACTION_UP,说明事件是在
                 LayoutView1上结束的,再看看测试结果2最后一条日志LayoutView2: onTouchEvent action:ACTION_UP说明事件是在
                  LayoutView2上结束的,再由于LayoutView1和LayoutView2的onTouchEvent()都返回了true,很明显可以看出事件传递的
                规律了。不同点:<1>那为什么LayoutView1的onTouchEvent() 也return true;却没有执行呢,那是因为,事件传递到了,LayoutView2
                的时候在onTouchEvent() return true对事件进行处理了,事件到此就结束了。则不会传递到父类ViewGroup的onTouchEvent()中去了。
               <2>看日志  LayoutView1: onInterceptTouchEvent action:ACTION_MOVE、LayoutView2: onTouchEvent action:ACTION_MOVE
                LayoutView1: onInterceptTouchEvent action:ACTION_UP、LayoutView2: onTouchEvent action:ACTION_UP,似乎和日志1中
               的“总结”有点矛盾了,为什么LayoutView1: onInterceptTouchEvent 在down的时候return false,还是会执行move、up,而看看
                LayoutView1: onInterceptTouchEvent 只执行ACTION_DOWN,却没有执行Move、up方法,完全符合测试1的结果,那是因为,在
                LayoutView1要把事件传递到子View中,因为子View中进行了事件处理。而LayoutView2却没有执行onInterceptTouchEvent()其Action_move
               、Action_up那是因为LayoutView2的子View不是一个ViewGroup,view没有onInterceptTouchEvent()方法。测试结果1和2主要区别就是测试2中
              子View进行了事件拦截,而测 试1中父View进行了事件拦截
  总结:事件拦截处理需要兼顾整个ViewGroup的所有子ViewGrop,最里层的View总是最先并且左后拦截事件。
 
 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     三、”外层View事件拦截“测试分析
     LayoutView1 
                      onInterceptTouchEvent() return true;                       *
                      onTouchEvent()          return true;                            *
     LayoutView2
                     onInterceptTouchEvent() return false;
                     onTouchEvent()          return false;    
  MyTextView
                   onTouchEvent()          return false;
    执行动作:滑动屏幕
    运行结果:
                 LayoutView1: onInterceptTouchEvent action:ACTION_DOWN
                 LayoutView1: onTouchEvent action:ACTION_DOWN
                 LayoutView1: onTouchEvent action:ACTION_MOVE
                 LayoutView1: onTouchEvent action:ACTION_UP
  分析及总结:由于最外层LayoutView1: onInterceptTouchEvent中ACTION_DOWN return true,直接表明对事件进行拦截,则事件不会再传递到LayoutView2

                 中直接交给    LayoutView1的onTouchEvent()进行处理
        
 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     四、”第二层View事件拦截“测试分析
     LayoutView1 
               onInterceptTouchEvent() return false;    
               onTouchEvent()          return true;                                        *
     LayoutView2
              onInterceptTouchEvent() return true;                                    *
              onTouchEvent()          return true;                                         *
     MyTextView
             onTouchEvent()          return false;
    执行动作:滑动屏幕
    运行结果:
            LayoutView1: onInterceptTouchEvent action:ACTION_DOWN
            LayoutView2: onInterceptTouchEvent action:ACTION_DOWN
            LayoutView2: onTouchEvent action:ACTION_DOWN
            LayoutView1: onInterceptTouchEvent action:ACTION_MOVE
            LayoutView2: onTouchEvent action:ACTION_MOVE
            LayoutView1: onInterceptTouchEvent action:ACTION_UP
            LayoutView2: onTouchEvent action:ACTION_UP
    分析及总结:根据日志LayoutView2: onInterceptTouchEvent ACTION_DOWN并没有执行move、up方法,因为返回true之后,会直接直接交给其onTouchEvent()
    方法,进行事件处理
   
   
  事件拦截总结:
           1、ViewGroup中的onInterceptTouchEvent如果返回true,则直接进行事件拦截,会调用OnTouchEvent()进行拦截后的事件处理。
           如果onInterceptTouchEvent返回false,则事件继续向下传递,最终由OnTouchEvent() return true,的viewGroup对事件
          进行处理,事件结束。如果没有OnTouchEvent() return true则传到最外层的ViewGroup的OnTouchEvent()事件结束。
           2、具体ViewGroup中的onInterceptTouchEvent如果返回false之后,onInterceptTouchEvent()后续的Move、up动作会不会执行
           完全取决于当前ViewGrop的子ViewGroup是否进行了拦截处理,如果进行了事件处理,则会执行后续的动作,反之不执行。

 

本人QQ:2521257722如果有写的不对的地方,请及时联系,或者有什么问题可以一起讨论。共同进步,谢谢!
     
 
  

你可能感兴趣的:(android)