美文网首页ViewAndroid知识Android开发
Android 触摸事件传递机制

Android 触摸事件传递机制

作者: 王世军Steven | 来源:发表于2017-02-17 12:57 被阅读70次

    Android 触摸事件传递机制

    1 触摸事件的类型

    • ACTION_DOWN : 用户手指按下操作,一般标志着触摸事件的开始.
    • ACTION_MOVE : 用户按下后移动手指.
    • ACTION_UP : 用户手指离开屏幕.触摸事件的结束.

    一次屏幕的触摸操作中,ACTION_UP 和 ACTION_DOWN 是必须有的.ACTION_MOVE视情况而定.

    2. 事件传递的三个阶段

    • 事件分发(dispatch) : 事件的分发对应着dispatchTouchEvent方法,在Android系统中所有的事件都是通过这个方法进行分发的.

      函数原型 :

      // 事件分发方法
      public boolean dispatchTouchEvent(MotionEvent ev);
      
      • 返回值 truefalse : 当前视图将事件消耗,不再继续分发给子视图.
      • 返回值 super.dispatchTouchEvent(ev) : 继续分发事件.
    • 事件拦截(Intercept) : 事件的拦截对应着onInterceptTouchEvent 方法.这个方法
      只有在ViewGroup及其子类中才存在,View和Activity中不存在.

      函数原型 :

      // 事件拦截
      public boolean onInterceptTouchEvent(MotionEvent ev);
      
      • 返回值 true : 拦截此事件,不再继续分发.同时交给自身的onTouchEvent方法进行消费.
      • 返回值 falsesuper.onInterceptTouchEvent : 不拦截事件,继续传递给子视图.
    • 事件消费(Consume) : 事件消费对应着 onTouchEvent 方法.

      函数原型 :

      // 消费函数
      public void onTouchEvent(MotionEvent ev);
      
      • 返回值 true : 当前视图可以处理当前事件,事件将不会向上传递给父视图.
      • 返回值 false : 当前视图处理不了该事件,事件会被传递给父视图的onTouchEvent方法进行处理.

    3. Android拥有事件传递处理能力的类

    • Activity : 拥有 dispatchTouchEventonTouchEvent 方法.
    • ViewGroup : dispatchTouchEventonInterceptTouchEventonTouchEvent
    • View : : dispatchTouchEventonTouchEvent

    4. View 的事件传递机制

    参考代码 : app , 下面对程序及结果进行分析.

    • 不进行人为干预. 不设置listener情况.

      • dispatchTouchEventonTouchEvent 返回父类的同名方法.
      • onTouch 返回 false

      运行结果 :

      MainActivity: dispatchTouchEvent : DOWN
      MyTextView: dispatchTouchEvent : DOWN
      MyTextView: onTouchEvent : DOWN
      MainActivity: onTouchEvent : DOWN
      MainActivity: dispatchTouchEvent : UP
      MainActivity: onTouchEvent : UP
      

      从LOG中可以看出事件传递方式如下 :

      • dispatchTouchEvent 方法从外层向内层传递.
      • onTouchEvent 从内层向外层传递.
      • 如果某一层处理了事,那么当前事件序列的其他事件不会向下传递.对于当前情况下由于MainActivity
        处理 ACTION_DOWN事件 所以该事件序列中的 ACTION_UP 事件也就到MainActivity就不
        再下发给子视图了.
    • 不进行人为干预,设置listener情况.

      onTouch返回false 运行结果 :

      MainActivity: dispatchTouchEvent : DOWN
      MyTextView: dispatchTouchEvent : DOWN
      MainActivity: onTouch : DOWN
      MyTextView: onTouchEvent : DOWN
      
      MainActivity: dispatchTouchEvent : UP
      MyTextView: dispatchTouchEvent : UP
      MainActivity: onTouch : UP
      MyTextView: onTouchEvent : UP
      
      MainActivity: MyTextView OnClick
      

      onTouch返回true 运行结果 :

      // onTouch 返回true : the listener consume the event
      MainActivity: dispatchTouchEvent : DOWN
      MyTextView: dispatchTouchEvent : DOWN
      MainActivity: onTouch : DOWN
      
      MainActivity: dispatchTouchEvent : UP
      MyTextView: dispatchTouchEvent : UP
      MainActivity: onTouch : UP
      

      LOG 信息显示事件是 MyTextView 视图处理的.

      • 事件处理的流程
        • 如果设置了listener则首先调用 listener 的 onTouch 方法.
          • 返回值 true : 表示listener处理该事件. onTouchEventonClick 不会被调用.
          • 返回值 false : 表示listener不处理该事件. onTouchEventOnClick 不会被调用.
        • onTouchEvent 如果onTouch 方法返回true
        • onClick 如果 onTouch 方法返回 true
    • dispatchTouchEvent 返回 falsetrue

      在两种情况下当前视图都会消耗该事件,该事件不会继续分发给子视图.
      同时不会调用onTouchEvent,onClick 等方法
      MainActivity 运行结果 :

      MainActivity: dispatchTouchEvent : DOWN
      MainActivity: dispatchTouchEvent : UP
      

      MyTextView 运行结果

      MainActivity: dispatchTouchEvent : DOWN
      MyTextView: dispatchTouchEvent : DOWN
      MainActivity: dispatchTouchEvent : UP
      MyTextView: dispatchTouchEvent : UP
      
    • onTouchEvent 方法返回 true

      当前视图消耗该事件,该事件处理不会向上传递. OnClick 方法不被调用

      MyTextView 运行结果

      MainActivity: dispatchTouchEvent : DOWN
      MyTextView: dispatchTouchEvent : DOWN
      MainActivity: onTouch : DOWN
      MyTextView: onTouchEvent : DOWN
      
      MainActivity: dispatchTouchEvent : UP
      MyTextView: dispatchTouchEvent : UP
      MainActivity: onTouch : UP
      MyTextView: onTouchEvent : UP
      
    • onTouchEvent 方法返回 false

      当前视图不处理该事件,事件将会被传递给上层控件处理.并且 onClick 不会被调用.

      MyTextView 运行结果

      MainActivity: dispatchTouchEvent : DOWN
      MyTextView: dispatchTouchEvent : DOWN
      MainActivity: onTouch : DOWN
      MyTextView: onTouchEvent : DOWN
      MainActivity: onTouchEvent : DOWN
      
      MainActivity: dispatchTouchEvent : UP
      MainActivity: onTouchEvent : UP
      
    • onTouchEvent 返回 super.onTouchEvent(ev)

      MyTextView 运行结果 :

      MainActivity: dispatchTouchEvent : DOWN
      MyTextView: dispatchTouchEvent : DOWN
      MainActivity: onTouch : DOWN
      MyTextView: onTouchEvent : DOWN
      
      MainActivity: dispatchTouchEvent : UP
      MyTextView: dispatchTouchEvent : UP
      MainActivity: onTouch : UP
      MyTextView: onTouchEvent : UP
      
      MainActivity: MyTextView OnClick
      
      

    5. ViewGroup 事件传递

    • onIntercepTouchEvent 返回 falsesuper.onIntercepTouchEvent

      在这种情况下,事件会继续分发.

      MyRelativeLayout 运行结果 :

      MainActivity: dispatchTouchEvent : DOWN
      MyRelativeLayout: dispatchTouchEvent : DOWN
      MyRelativeLayout: onInterceptTouchEvent : DOWN
      MyTextView: dispatchTouchEvent : DOWN
      MainActivity: onTouch : DOWN
      MyTextView: onTouchEvent : DOWN
      MainActivity: dispatchTouchEvent : UP
      MyRelativeLayout: dispatchTouchEvent : UP
      MyRelativeLayout: onInterceptTouchEvent : UP
      MyTextView: dispatchTouchEvent : UP
      MainActivity: onTouch : UP
      MyTextView: onTouchEvent : UP
      MainActivity: MyTextView OnClick
      
    • onInterceptTouchEvent 返回 true

      在这种情况下,此视图会拦截事件,并交给自身的 onTouchEvent 处理.
      MyRelativeLayout 运行结果 :

      // 事件最终是Activity处理的.
      MainActivity: dispatchTouchEvent : DOWN
      MyRelativeLayout: dispatchTouchEvent : DOWN
      MyRelativeLayout: onInterceptTouchEvent : DOWN
      MyRelativeLayout: onTouchEvent : DOWN
      MainActivity: onTouchEvent : DOWN
      MainActivity: dispatchTouchEvent : UP
      MainActivity: onTouchEvent : UP
      

    代码地址 : https://github.com/RichardFrankios/AndroidAdvanced

    相关文章

      网友评论

        本文标题:Android 触摸事件传递机制

        本文链接:https://www.haomeiwen.com/subject/wxakwttx.html