View 触摸事件分发拦截机制(一)

四个重要方法


整个事件分发 拦截 处理 主要是靠这四个方法
- dispatchTouchEvent 事件分发方法
- onInterceptTouchEvent 事件拦截方法
- onTouchEvent 事件处理
- requestDisallowInterceptTouchEvent 驳回拦截

@Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        boolean consume=false;

        if(onInterceptTouchEvent(ev)){
            consume=onTouchEvent(ev);
        }else {
            consume=child.dispatchTouchEvent(ev);
        }

        return consume;
    }
这是一段伪代码基本把上述的前三个方法关系解释的非常清楚了.

dispatchTouchEvent (MotionEvent ev)

本类的分发者 告诉外界我们怎么搞,已经分发处理

返回值
- true 整个循环结束
- false 表示没人处理
- super 无论是返回true 还是false 都不要这么做 父类已经封装了很多判断,如果直接返回一个true/false,都会影响其它方法(一般不要重写该方法)

dispatchTouchEvent 我是负责事件分发的 事件先到我这了,
我就问下onInterceptTouchEvent 事件拦截方法
onInterceptTouchEvent(返回true) 我们拦截 这事我们干
所以dispatchTouchEvent就调用onTouchEvent来处理
onInterceptTouchEvent(返回false) 我们不管 
所以dispatchTouchEvent就调用他子View的的dispatchTouchEvent 交给下面做

onInterceptTouchEvent (MotionEvent ev)

本类的消息处理决定者 告诉dispatchTouchEvent我们是否拦截
  • true 进行拦截 告诉dispatchTouchEvent我们来处理
  • false 不拦截 告诉dispatchTouchEvent我们不管

onTouchEvent(MotionEvent ev)

本类的事件真正的处理者
  • true 反馈上级 事情我做了 消耗掉了
  • false 反馈上级 这事情我不想做 不做了
@Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                break;

            case MotionEvent.ACTION_MOVE:
                break;

            case MotionEvent.ACTION_UP:
                break;
        }
        return true;
    }
一般都会按照上面的写法来处理事件
ACTION_DOWN 必定会执行一次,如果除ACTION_DOWN以外的事件没有消耗掉的化,
这点击事件就会流失,交给父控件了

requestDisallowInterceptTouchEvent(boolean disallowIntercept)

驳回拦截事件
  • true 上级拦截全部无效,这事件交给我
  • false 什么也没发生

事件传递规则


  • 事件到来向下传递Activity→Window→ViewGroup→View 一层一层向下传递,当有控件拦截时 则不在向下传递
  • 事件反馈从下往上传递 自己不处理交给父类来处理

你可能感兴趣的:(基础总结)