zoukankan      html  css  js  c++  java
  • onInterceptTouchEvent和onTouchEvent调用关系详解

    本帖记录onInterceptTouchEvent和onTouchEvent调用关系,即各种return true和return false的运行情况。


    return true和return false,代表的是是否消费完该事件,也就是该事件是否会继续传递给下层或者上层组件继续处理。return true代表消费完不会继续传递,return false代表没有消费完将会继续传递。

    如果没有onInterceptTouchEvent,只考虑onTouchEvent的话,比较容易分析和理解。假如有三层布局结构,linearLayout1,linearLayout2,textView,从前到后是包含的关系。那么下面分情况说明。
    1. 如果它们的onTouchEvent都返回false的话,DOWN事件会自上而下(textView位于最上层)依次传递,最终都没有消费完此事件,都 只会进入onTouchEvent方法一次并且MotionEvent的action为MotionEvent.ACTION_DOWN,move和up 等事件不会继续处理。
    2.如果textView的onTouchEvent返回true,表示textView消费了此事件,不会传给父组件linearLayout2和linearLayout1了,并且还会继续处理move和up等事件。
    3.linearLayout2和linearLayout1的onTouchEvent返回true和上面的情况一样,都不会继续传给父容器而且本身继续处理move和up等事件。
    OK,这种情况还是比较容易理解的。

    下面加入onInterceptTouchEvent。
    onInterceptTouchEvent只有ViewGroup才会有,用于在进入自身onTouchEvent或者子组件onTouchEvent之前处理事件。注意onTouch是自上而下传递,而onInterceptTouch却是由下而上传递的。来了一个DOWN事件,首先进入的必然是最底层的viewGroup的onInterceptTouchEvent方法,然后根据return的值进入自身或者子组件的onTouch事件,当然如果子组件也是viewgroup的话,在进入子组件的onTouch之前也会进入子组件的onInterceptTouchEvent方法。
    下面也分几种情况介绍:
    1.当onInterceptTouchEvent返回false时,表示没有消费完此事件,会继续传递个子组件的onTouch继续处理。注意这种情况不会就不会传递给这个ViewGroup自身的onTouch事件处理了。这和onTouch如果返回false,后续的move、up等事件都不会继续处理了可以做同样理解。
    2.当onInterceptTouchEvent返回true时,表示消费完此事件,或者说将在此组件上消费该事件。这种情况该事件会传递给ViewGroup自身的onTouch事件去处理,而不会传递给子组件的onTouch方法了。
    由 此可以总结,onInterceptTouchEvent返回值只是决定了是要把事件传递给自身的onTouch事件还是传递给子组件的onTouch事 件。返回false表示没有消费完将传递个子组件的onTouch方法,返回true表示自身消费此事件,将传递给自身的onTouch方法而不会传递给 子组件的onTouch方法了。

    流程图

    阻止事件和分发事件:
    
     1 
     6 public class MyLinearLayout extends LinearLayout {
     7 
     8 
     9     public MyLinearLayout(Context context, AttributeSet attrs) {
    10         super(context, attrs);
    11     }
    12 
    13     /**
    14      * 中断事件
    15      */
    16     @Override
    17     public boolean onInterceptTouchEvent(MotionEvent ev) {
    18         return true;
    19     }
    20 
    21     /**
    22      * 分发事件
    23      */
    24     @Override
    25     public boolean dispatchTouchEvent(MotionEvent ev) {
    26         return super.dispatchTouchEvent(ev);
    27     }
    28     
    29     /**
    30      * 实现多个ListView控件同时触发事件
    31      */
    32     @Override
    33     public boolean onTouchEvent(MotionEvent event) {
    34         
    35         int width=getWidth()/getChildCount();
    36         int height = getHeight();
    37         int count=getChildCount();
    38         
    39         float eventX = event.getX();
    40         
    41         if (eventX<width){    // 滑动左边的 listView
    42             event.setLocation(width/2, event.getY());
    43             getChildAt(0).dispatchTouchEvent(event);//移动位置后,分发事件
    44             return true;
    45             
    46         } else if (eventX > width && eventX < 2 * width) { //滑动中间的 listView  
    47             float eventY = event.getY();
    48             if (eventY < height / 2) {
    49                 event.setLocation(width / 2, event.getY());
    50                 for (int i = 0; i < count; i++) {
    51                     View child = getChildAt(i);
    52                     try {
    53                         child.dispatchTouchEvent(event);
    54                     } catch (Exception e) {
    55                         e.printStackTrace();
    56                     }
    57                     
    58                 }
    59                 return true;
    60             } else if (eventY > height / 2) {
    61                 event.setLocation(width / 2, event.getY());
    62                 try {
    63                     getChildAt(1).dispatchTouchEvent(event);
    64                 } catch (Exception e) {
    65                     e.printStackTrace();
    66                 }
    67                 return true;
    68             }
    69         }else if (eventX>2*width){
    70             event.setLocation(width/2, event.getY());
    71             getChildAt(2).dispatchTouchEvent(event);
    72             return true;
    73         }
    74         
    75         return true;
    76     }
    77     
    78 }
  • 相关阅读:
    vue开发(一)安装
    Ubuntu18.04安装mysql
    使用.NET Framework开发IIS 7.0模块和处理程序拦截请求实现跳转
    Mysql 清空数据后,释放硬盘文件
    依赖注入
    ubuntu 上开发.netcore
    使用python获取微医数据
    Mysql查询某字段重复值并删除重复值
    使用pyinstaller 打包python程序
    堆(heap)和栈(stack)、内存泄漏(memory leak)和内存溢出
  • 原文地址:https://www.cnblogs.com/maxiaodoubao/p/4045813.html
Copyright © 2011-2022 走看看