温故而知新,系统整理一下。

1. View是什么?

1. 触摸事件的基本类型
     1). down: 按下
     2). move: 移动
     3). up: 离开

2. 事件对象产生的顺序

1). down-->move-->move-->....-->up
2). 每个事件对象产生后, 都会找到一个消费者来消费处理此事件

3. 事件相关API

     1). MotionEvent: 代表对UI的操作单元的类, 它的对象在用户触摸UI时系统自动创建基对象, 并将相关的数据保存在此对象中
ACTION_DOWN=0 : down类型值ACTION_UP=1 : up类型值 ACTION_MOVE=2 : move类型值 int getAction() : 得到事件类型值
float getX() : 得到事件的X轴坐标(相对于当前View的左顶点)float getRawX() : 得到事件的X轴坐标(相对于屏幕的左顶点)float getY() : 得到事件的Y轴坐标(相对于当前View的左顶点)
float getRawY() : 得到事件的Y轴坐标(相对于屏幕的左顶点)
     2). Activity
               boolean dispatchTouchEvent(MotionEvent event) : 分发事件  
               boolean onTouchEvent(MotionEvent event) : 处理事件的回调
     3). View
               boolean dispatchTouchEvent(MotionEvent event): 分发事件

               setOnClickListener(OnClickListener l) : 设置触摸事件监听器对象
               private OnTouchListener mOnTouchListener; //触摸事件监听器对象变量
               public interface OnTouchListener {  //事件监听器接口
                  boolean onTouch(View v, MotionEvent event);  // 监听器对象的回调方法
               }

               boolean onTouchEvent(MotionEvent event)  : 事件监听回调方法

               setOnclickListener(OnclickListener listener) : 设置点击监听器
               setOnLongClickListener(OnLongClickListener listener) : 设置长按事件监听器
     4). ViewGroup
               boolean dispatchTouchEvent(MotionEvent ev) : 重写View的此方法, 如果当前ViewGroup不拦截, 会分发给对应的子View处理事件
               boolean onInterceptTouchEvent(MotionEvent ev) : 拦截触摸事件, 返回值如果为true表示拦截,后面的事件就会交给当前View来处理, 默认为false
               requestDisallowInterceptTouchEvent(boolean disallowIntercept) : 如果参数为true, 使当前View及其外层的所有父View不能拦截后面的事件

4. View的事件处理

1). Touch事件的方法执行顺序: 
     ①. dispatchTouchEvent()
     ②. setOnTouchListener的onTouch()
     ③. onTouchEvent()
2). 执行的详细过程
     ①. 在dispatchTouchEvent()会判断是否设置了Touch监听器?
          如果没有直接进入②
          如果有, 调用监听器的onTouch()方法, 如果onTouch方法返回true到此结束, 如果返回false进入②
     ②. 调用onTouchEvent()
          在down时, send一个延时500ms的消息准备触发长按事件监听回调)
          如果0.5s内在产生了up事件, 此时就会移除长按的延时消息, 就会去执行点击事件监听回调
          如果0.5内没有产生up事件, 也没有离开, 就会调用长按事件监听回调方法, 如果返回的值是true就不可能再触发点击监听回调了, 否则还会触发.
3). 说明:
     ①. 如果view的onTouch()(监听器回调)或onTouchEvent(监听回调)在down时返回true, 那第一个move事件就会交给当前View处理, 
          否则后面的所有事件都不会到达此View了
     ②. 如是move事件处理返回true, 下一个move/up事件就会交给当前View处理,否则就会找父View或Activity处理
     ③. 整体原则: 每个Event对象创建后, 最终肯定会有一个消费者: 可能是View, 也可能是ViewGroup, 实在不行就交给Activty消费处理

5. ViewGroup的事件处理

1). 相关方法执行顺序:
     ①. dispatchTouchEvent()
     ②.onInterceptTouchEvent()
     ③. 对应子View的dispatchTouchEvent()
2). 执行的详细过程:
     ①. 在dispatchTouchEvent()中, ACTION_DOWN时, 判断是否拦截,如果没有拦截,则找到包含当前x,y坐标的子View,赋值给mMotionTarget,
          然后调用mMotionTarget.dispatchTouchEvent()处理down事件
     ②. 在dispatchTouchEvent()中, ACTION_MOVE时, 判断是否拦截,如果没有拦截,则直接调用mMotionTarget.dispatchTouchEvent(ev)
     ③. 在dispatchTouchEvent()中, ACTION_UP时, 判断是否拦截,如果没有拦截,则直接调用mMotionTarget.dispatchTouchEvent(ev)
     ④. 如果没有找到合适的子View来消费当前event, 则将自己当成View来处理event
3). 关于拦截:
     ①. 如何拦截?: ViewGroup中onInterceptTouchEvent()默认返回false, 也就是不拦截, 如果想拦截就重写此方法, 并返回true, 这样事件就不会分发给子View处理
     ②. 如何不被拦截?: 如果子View不希望父View(也就是当前ViewGroup)拦截event, 子View可以执行: getParent().requestDisallowInterceptTouchEvent(true)

——相关资料推荐
Android View 事件分发机制 源码解析
Android ViewGroup事件分发机制
Android事件分发机制完全解析,带你从源码的角度彻底理解(上)
Android事件分发机制完全解析,带你从源码的角度彻底理解(下)

android触摸事件处理流程
Android应用层View绘制流程与源码分析

Android View刷新机制