zoukankan      html  css  js  c++  java
  • 事件分发机制

    事件分发机制

    1、单个view中的事件分发

      单个view的touch事件处理会触发两个方法  :

     dispatchTouchEvent(MotionEvent event);

     onTouchEvent(MotionEvent event);

    当出现touch事件时:

           先执行dispatchTouchEvent事件的down事件,然后在执行onTouchEvent事件的down事件,当onTouchEvent事件的down事件返回值为true时,dispatchTouchEvent方法也返回true,且把以后的move事件,up事件都传给onTouch。之后的move事件及up事件的返回值,onTouch返回什么dispatchTouchEvent也返回什么。
         相反如果传第一个down事件给ontouch的时候,ontouch返回的是false,从此事件不再会传过来,也就是不会走dispatchTouchEvent。更不会走ontouchevent。

    return true就意味着该view会继续处理抬起事件,而不会将此时间传递给父View---------这也意味着只有一个view可以继续监听touch事件。

    2、Activity中view的事件分发

    Activity中view的touch事件处理会触发activity和view的两个方法  :

     dispatchTouchEvent(MotionEvent event);

     onTouchEvent(MotionEvent event);

    dispatchTouchEvent方法是从父View向子View传递,而onTouchEvent方法是从子View向父View传递。

    事件执行顺序:

    在不做任何处理的情况下,先触发activity中dispatchTouchEvent的down事件,再触发子view中的dispatchTouchEvent的down事件,再触发子view的setOnTouchListener中的onTouch事件,再触发子view中的onTouchEvent的down事件,最后再向上传递触发activity的onTouchEvent的down事件;然后由于子view未处理down事件,随着手势动作,触发activity中dispatchTouchEvent的move事件,接着再触发activity中onTouchEvent的move事件,然后再出发activity中dispatchTouchEvent的up事件,然后在触发activity中onTouchEvent的up事件。

    特殊情况:

    1. 当activity中的dispatchTouchEvent中的down事件返回值为true时,意味着activity要处理该事件,因此事件不在向下传递,而是直接执行activity中dispatchTouchEvent中的move或者up事件,再执行onTouchEvent的move或者up事件。
    2. 当activity中的dispatchTouchEvent中的down事件返回值为false时,意味着activity不处理该事件,事件也不会向下传递,也不会执行activity中的onTouchEvent的down事件,而是直接执行dispatchTouchEvent中的move或者up事件,然后再执行onTouchEvent的move或者up事件。
    3. 当activity中的dispatchTouchEvent中的down事件不做任何处理时,事件会向子view中传递,触发子view中的dispatchTouchEvent中的down事件,当此方法返回值为true时,代表该方法要处理此事件,因此事件不会再向下传递,接着会触发activity中的disaptchTouchEvent的move或者up事件,接着再向下传递,触发自view中的dispatchTouchEvent的move或者up事件,接着再触发 view的setOnTouchListener中的onTouch事件,再触发子view中的onTouchEvent的move或者up事件,最后再向上传递触发activity的onTouchEvent的move或者up事件。
      1.   当activity中的dispatchTouchEvent中的down事件不做任何处理时,事件会向子view中传递,触发子view中的dispatchTouchEvent中的down事件,当此方法返回值为false时,代表子view不会处理此事件,接着再向上传递触发activity的onTouchEvent的down事件,接着触发activity中的dispatchTouchEvent的move或者up事件,由于子view已经申明不会处理该事件,因此事件不会再向下传递,而是直接触发activity中的onTouchEvent的move或者up事件。
      2.   当activity中的dispatchTouchEvent中的down事件不做任何处理时,事件会向子view中传递,触发子view中的dispatchTouchEvent中的down事件,当该方法也不做任何处理时,再触发view的setOnTouchListener中的onTouch事件,接着再触发view的onTouchEvent的down事件,当该方法返回值为true时,意味着view要处理此事件,因此事件不再向上传递,而是接着触发activity中的dispatchTouchEvent的move或者up事件,由于子view要处理该事件,因此事件会再向下传递,触发view中的dispatchTouchEvent的move或者up事件,再触发view的setOnTouchListener中的onTouch事件,接着再触发view的onTouchEvent的move或者up事件,接着事件再向上传递触发activity中的onTouchEvent的move或者up事件。
      3. 当activity中的dispatchTouchEvent中的down事件不做任何处理时,事件会向子view中传递,触发子view中的dispatchTouchEvent中的down事件,当该方法也不做任何处理时,再触发view的setOnTouchListener中的onTouch事件,接着再触发view的onTouchEvent的down事件,当该方法返回值为false时,意味着view不处理此事件,因此事件再向上传递,触发activity的onTouchEvent的down事件,接着触发activity中的dispatchTouchEvent的move或者up事件,由于子view不处理该事件,因此事件不会再向下传递,而是触发触发activity中的onTouchEvent的move或者up事件。

    3 ViewGroup的事件分发机制

           在触发OnTouch事件的时候Android的ViewGroup会调用如下三个函数:

         public boolean dispatchTouchEvent(MotionEvent ev)      //用于事件的分发

         public boolean onInterceptTouchEvent(MotionEvent ev)    //  用于事件的拦截

         public boolean onTouchEvent(MotionEvent ev)     //处理事件

         对于ViewGroup类的控件,有一个很重要的方法,就是onInterceptTouchEvent(),用于处理事件并改变事件的传递方向,它的返回值是一个布尔值,决定了Touch事件是否要向它包含的子View继续传递,这个方法是从父View向子View传递。而方法onTouchEvent(),用于接收事件并处理,它的返回值也是一个布尔值,决定了事件及后续事件是否继续向上传递,这个方法是从子View向父View传递。touch事件在 onInterceptTouchEvent()和onTouchEvent以及各个childView间的传递机制完全取决于onInterceptTouchEvent()和onTouchEvent()的返回值。返回值为true表示事件被正确接收和处理了,返回值为false表示事件没有被处理,将继续传递下去。

           ACTION_DOWN事件会传到某个ViewGroup类的onInterceptTouchEvent,如果返回false,则DOWN事件继续向子ViewGroup类的onInterceptTouchEvent传递,如果子View不是ViewGroup类的控件,则传递给它的onTouchEvent。

          如果onInterceptTouchEvent返回了true,则DOWN事件传递给它的onTouchEvent,不再继续传递,并且之后的后续事件也都传递给它的onTouchEvent。
         如果某View的onTouchEvent返回了false,则DOWN事件继续向其父ViewGroup类的onTouchEvent传递;如果返回了true,则后续事件会直接传递给其onTouchEvent继续处理。(后续事件只会传递给对于必要事件ACTION_DOWN返回了true的onTouchEvent。

    onInterceptTouchEvent()用于处理事件并改变事件的传递方向。处理事件这个不用说了,你在函数内部编写代码处理就可以了。而决定传递方向的是返回值,返回为false时事件会传递给子控件的onInterceptTouchEvent();返回值为true时事件会传递给当前控件的onTouchEvent(),而不在传递给子控件,这就是所谓的Intercept(截断)。

         切记: onTouchEvent() 用于处理事件,返回值决定当前控件是否消费(consume)了这个事件。可能你要问是否消费了又区别吗,反正我已经针对事件编写了处理代码?答案是有区别!比如ACTION_MOVE或者ACTION_UP发生的前提是一定曾经发生了ACTION_DOWN,如果你没有消费ACTION_DOWN,那么系统会认为ACTION_DOWN没有发生过,所以ACTION_MOVE或者ACTION_UP就不能被捕获。

  • 相关阅读:
    前端学习 -- Css -- 盒子模式
    前端学习 -- Css -- 文本样式
    Shell脚本学习
    前端学习 -- Css -- 行间距
    前端学习 -- Css -- 字体的几个属性学习
    前端学习 -- Css -- 字体分类
    前端学习 -- Css -- 字体
    前端学习 -- 颜色
    前端学习 -- 长度单位
    前端学习 -- Css -- 定义列表
  • 原文地址:https://www.cnblogs.com/ruirui2015/p/4923559.html
Copyright © 2011-2022 走看看