http://blog.csdn.net/yanbober/article/details/45887547/
【工匠若水 http://blog.csdn.net/yanbober】此博主分析的已经很详细了,我只是借鉴一下。

先把代码贴上:

public class MainActivity extends AppCompatActivity {

    private TouchView view;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        view = (TouchView) findViewById(R.id.touch_view);
        view.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                Log.d("TAG","setOnTouchListener ->"+motionEvent.getAction());
                return false;
            }
        });
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d("TAG","onClick ");

            }
        });
    }
}
mainActivity布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.xxha.xh.viewontouch.MainActivity">

    <com.xxha.xh.viewontouch.TouchView
        android:id="@+id/touch_view"
        android:background="@color/colorAccent"
        android:layout_width="100dp"
        android:layout_height="100dp"
         />
</RelativeLayout>

自定义的touchView类

/**
 * Created by Lm on 2017/10/18.
 * Email:1002464056@qq.com
 */

public class TouchView extends View {
    public TouchView(Context context) {
        super(context);
    }

    public TouchView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TouchView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.d("TAG","onTouchEvent ->"+event.getAction());
        return super.onTouchEvent(event);
    }
}

运行,点击控件,运行结果为
10-18 14:42:51.154 31628-31628/com.xxha.xh.viewontouch D/TAG: setOnTouchListener ->0
10-18 14:42:51.154 31628-31628/com.xxha.xh.viewontouch D/TAG: onTouchEvent ->0
10-18 14:42:51.233 31628-31628/com.xxha.xh.viewontouch D/TAG: setOnTouchListener ->2
10-18 14:42:51.233 31628-31628/com.xxha.xh.viewontouch D/TAG: onTouchEvent ->2
10-18 14:42:51.250 31628-31628/com.xxha.xh.viewontouch D/TAG: setOnTouchListener ->2
10-18 14:42:51.250 31628-31628/com.xxha.xh.viewontouch D/TAG: onTouchEvent ->2
10-18 14:42:51.251 31628-31628/com.xxha.xh.viewontouch D/TAG: setOnTouchListener ->1
10-18 14:42:51.251 31628-31628/com.xxha.xh.viewontouch D/TAG: onTouchEvent ->1
10-18 14:42:51.251 31628-31628/com.xxha.xh.viewontouch D/TAG: onClick

结论:
1. Android控件的Listener事件触发顺序是先触发onTouch,其次onClick。
2. 如果控件的onTouch返回true将会阻止事件继续传递,返回false事件会继续传递。

看一下源码(只贴重点):

 public boolean dispatchTouchEvent(MotionEvent event) {
         ......(只贴重点)
         boolean result = false;
         ......
          if (li != null && li.mOnTouchListener != null
                    && (mViewFlags & ENABLED_MASK) == ENABLED
                    && li.mOnTouchListener.onTouch(this, event)) {
                result = true;
            }

            if (!result && onTouchEvent(event)) {
                result = true;
            }
 }

两个if 方法中 li指的是触摸对象,不为null,li.mOnTouchListener指的是对象设置了OnTouchListener监听,也不为null ,enable指的是控件是否可用(默认可用),最关键的是onTouch(), 如果onTouch返回ture则,if语句执行,反之不执行。

从而推断出触摸程序的执行顺序为 :一触摸就执行dispatchTouchEvent,然后执行 onTouch() 方法。
1.若onTouch为true,则result 为true,继而下面的if (!result && onTouchEvent(event))中,!result为flase了就不会执行onTouchEvent()方法
2.若onTouch为false,则result 为fasle,继而下面的if (!result && onTouchEvent(event))中,!result为true,就会继续执行onTouchEvent(),判断onTouchEvent()的返回值。

再次推断程序的执行顺序为:一触摸就执行dispatchTouchEvent,然后执行 onTouch() 方法,然后执行 onTouchEvent()方法

dispatchTouchEvent()方法分析完后没有看到onClick()方法在哪里执行的,也就是说onclick()应该与onTouchEvent有关系。
直接给出结论不再具体分析:
1. onTouchEvent方法中会在ACTION_UP分支中触发onClick的监听。
2. 当dispatchTouchEvent在进行事件分发的时候,只有前一个action返回true,才会触发下一个action。

时间太仓促,来不及写了,大体执行过程就是这样。

综合得出Android View的触摸屏事件传递机制有如下特征:

  1. 触摸控件(View)首先执行dispatchTouchEvent方法。
  2. 在dispatchTouchEvent方法中先执行onTouch方法,后执行onClick方法(onClick方法在onTouchEvent中执行,下面会分析)。
  3. 如果控件(View)的onTouch返回false或者mOnTouchListener为null(控件没有设置setOnTouchListener方法)或者控件不是enable的情况下会调运onTouchEvent,dispatchTouchEvent返回值与onTouchEvent返回一样。
  4. 如果控件不是enable的设置了onTouch方法也不会执行,只能通过重写控件的onTouchEvent方法处理(上面已经处理分析了),dispatchTouchEvent返回值与onTouchEvent返回一样。
  5. 如果控件(View)是enable且onTouch返回true情况下,dispatchTouchEvent直接返回true,不会调用onTouchEvent方法。
  6. 当dispatchTouchEvent在进行事件分发的时候,只有前一个action返回true,才会触发下一个action(也就是说dispatchTouchEvent返回true才会进行下一次action派发)。