Android事件传递机制详解

来源:互联网 发布:电脑屏幕校准软件 编辑:程序博客网 时间:2024/05/17 08:38

总结

dispatchTouchEvent方法:分发点击事件
onInterceptTouchEvent方法:拦截事件(只存在于ViewGroup,View没有此方法), 在dispatchTouchEvent方法内部调用
onTouchEvent方法:处理点击事件,在dispatchTouchEvent方法内部调用

示例代码

自定义View-MyLinearLayout

public class MyLinearLayout extends LinearLayout {    private static String TAG = "test";    public MyLinearLayout(Context context) {        this(context,null);    }    public MyLinearLayout(Context context, @Nullable AttributeSet attrs) {        this(context, attrs, 0);    }    public MyLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initView(context);    }    private void initView(Context context) {    }    @Override    public boolean dispatchTouchEvent(MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                Log.d(TAG, "MyLinearLayout-dispatchTouchEvent-down");                break;            case MotionEvent.ACTION_MOVE:                Log.d(TAG, "MyLinearLayout-dispatchTouchEvent-move");                break;            case MotionEvent.ACTION_UP:                Log.d(TAG, "MyLinearLayout-dispatchTouchEvent-up");                break;            case MotionEvent.ACTION_CANCEL:                Log.d(TAG, "MyLinearLayout-dispatchTouchEvent-cancel");                break;        }        return super.dispatchTouchEvent(event);    }    @Override    public boolean onInterceptTouchEvent(MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                Log.d(TAG, "MyLinearLayout-onInterceptTouchEvent-down");                break;            case MotionEvent.ACTION_MOVE:                Log.d(TAG, "MyLinearLayout-onInterceptTouchEvent-move");                break;            case MotionEvent.ACTION_UP:                Log.d(TAG, "MyLinearLayout-onInterceptTouchEvent-up");                break;            case MotionEvent.ACTION_CANCEL:                Log.d(TAG, "MyLinearLayout-onInterceptTouchEvent-cancel");                break;        }        return super.onInterceptTouchEvent(event);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                Log.d(TAG, "MyLinearLayout-onTouchEvent-down");                break;            case MotionEvent.ACTION_MOVE:                Log.d(TAG, "MyLinearLayout-onTouchEvent-move");                break;            case MotionEvent.ACTION_UP:                Log.d(TAG, "MyLinearLayout-onTouchEvent-up");                break;            case MotionEvent.ACTION_CANCEL:                Log.d(TAG, "MyLinearLayout-onTouchEvent-cancel");                break;        }        return super.onTouchEvent(event);    }}

自定义View-MyButton

public class MyButton extends android.support.v7.widget.AppCompatButton {    private static String TAG = "test";    public MyButton(Context context) {        this(context, null);    }    public MyButton(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public MyButton(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initView(context);    }    private void initView(Context context) {    }    @Override    public boolean dispatchTouchEvent(MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                Log.d(TAG, "MyButton-dispatchTouchEvent-down");                break;            case MotionEvent.ACTION_MOVE:                Log.d(TAG, "MyButton-dispatchTouchEvent-move");                break;            case MotionEvent.ACTION_UP:                Log.d(TAG, "MyButton-dispatchTouchEvent-up");                break;            case MotionEvent.ACTION_CANCEL:                Log.d(TAG, "MyButton-dispatchTouchEvent-cancel");                break;        }        return super.dispatchTouchEvent(event);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                Log.d(TAG, "MyButton-onTouchEvent-down");                break;            case MotionEvent.ACTION_MOVE:                Log.d(TAG, "MyButton-onTouchEvent-move");                break;            case MotionEvent.ACTION_UP:                Log.d(TAG, "MyButton-onTouchEvent-up");                break;            case MotionEvent.ACTION_CANCEL:                Log.d(TAG, "MyButton-onTouchEvent-cancel");                break;        }        return super.onTouchEvent(event);    }}

MainActivity

public class TestActivity extends AppCompatActivity {    private MyLinearLayout mLlRoot;    private MyButton mBtn1;    private static String TAG = "test";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_three);        initView();    }    private void initView() {        mLlRoot = (MyLinearLayout) findViewById(R.id.ll_root);        mBtn1 = (MyButton) findViewById(R.id.btn1);    }    @Override    public boolean dispatchTouchEvent(MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                Log.d(TAG, "Activity-dispatchTouchEvent-down");                break;            case MotionEvent.ACTION_MOVE:                Log.d(TAG, "Activity-dispatchTouchEvent-move");                break;            case MotionEvent.ACTION_UP:                Log.d(TAG, "Activity-dispatchTouchEvent-up");                break;            case MotionEvent.ACTION_CANCEL:                Log.d(TAG, "threeActivity-dispatchTouchEvent-cancel");                break;        }        return super.dispatchTouchEvent(event);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                Log.d(TAG, "Activity-onTouchEvent-down");                break;            case MotionEvent.ACTION_MOVE:                Log.d(TAG, "Activity-onTouchEvent-move");                break;            case MotionEvent.ACTION_UP:                Log.d(TAG, "Activity-onTouchEvent-up");                break;            case MotionEvent.ACTION_CANCEL:                Log.d(TAG, "Activity-onTouchEvent-cancel");                break;        }        return super.onTouchEvent(event);    }}

布局文件

<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent">    <com.cn.liuyz.javademo.autoView.MyLinearLayout        android:id="@+id/ll_root"        android:layout_width="match_parent"        android:orientation="horizontal"        android:background="#888"        android:layout_height="500dp">        <com.cn.liuyz.javademo.autoView.MyButton            android:id="@+id/btn1"            android:text="你好"            android:background="#f00"            android:layout_width="200dp"            android:layout_gravity="center"            android:layout_height="200dp"/>    </com.cn.liuyz.javademo.autoView.MyLinearLayout></LinearLayout>

默认情况下事件传递

从Activity –> ViewGroup(MyLinearLayout) –> View(MyButton),从上往下调用dispatchTouchEvent()

再由View(MyButton) –> ViewGroup(MyLinearLayout) –> Activity,从下往上调用onTouchEvent()

ViewGroup中

dispatchTouchEvent

dispatchTouchEvent返回super.dispatchTouchEvent(event)

  • 调用dispatchTouchEvent方法内部的onInterceptTouchEvent方法

dispatchTouchEvent返回true

  • 消费事件,事件不会往下传递
  • dispatchTouchEvent后续的ACTION_MOVE、ACTION_UP事件继续执行(后续事件会继续分发到该ViewGroup)

dispatchTouchEvent返回false

  • 不消费事件,事件停止传递
  • 将事件向上传给父控件的onTouchEvent处理
  • dispatchTouchEvent后续的ACTION_MOVE、ACTION_UP事件不再执行(后续事件将不会分发给该ViewGroup)

onInterceptTouchEvent

onInterceptTouchEvent返回super.onInterceptTouchEvent(event)

  • 不拦截事件,事件继续往下传递
  • onInterceptTouchEvent后续的ACTION_MOVE、ACTION_UP事件不再执行
  • 同一个事件序列中同一个ViewGroup的onInterceptTouchEvent方法只会调用一次

onInterceptTouchEvent返回true

  • 拦截事件,事件不会往下传递
  • 传递给自己的onTouchEvent处理
  • onInterceptTouchEvent后续的ACTION_MOVE、ACTION_UP事件不再执行

onInterceptTouchEvent返回false

  • 不拦截事件,事件继续往下传递
  • onInterceptTouchEvent后续的ACTION_MOVE、ACTION_UP事件不再执行
  • ViewGroup默认是不拦截的,所以super==false

onTouchEvent

onTouchEvent返回super.onTouchEvent(event)

  • 不消费事件,事件继续往上传递
  • onTouchEvent后续的ACTION_MOVE、ACTION_UP事件不再执行(后续事件将不会分发给该ViewGroup)

onTouchEvent返回true

  • 处理事件,事件停止传递
  • onTouchEvent后续的ACTION_MOVE、ACTION_UP事件继续执行(后续事件会继续分发到该ViewGroup)

onTouchEvent返回false

  • 不处理事件,传递给父控件onTouchEvent处理
  • onTouchEvent后续的ACTION_MOVE、ACTION_UP事件不再执行(后续事件将不会分发给该ViewGroup)

View中

dispatchTouchEvent

dispatchTouchEvent返回super.dispatchTouchEvent(event)

  • 调用dispatchTouchEvent方法内部的onTouchEvent方法
  • 是否消费事件取决于onTouchEvent的返回值

dispatchTouchEvent返回true

  • 消费事件,事件不会往下传递
  • dispatchTouchEvent后续的ACTION_MOVE、ACTION_UP事件继续执行(后续事件会继续分发到该ViewGroup)

dispatchTouchEvent返回false

  • 不消费事件
  • 将事件向上传给父控件的onTouchEvent处理
  • dispatchTouchEvent后续的ACTION_MOVE、ACTION_UP事件不再执行(后续事件将不会分发给该ViewGroup)

onTouchEvent

onTouchEvent返回super.onTouchEvent(event)

  • 不处理事件,事件继续往上传递
  • onTouchEvent后续的ACTION_MOVE、ACTION_UP事件不再执行

onTouchEvent返回true

  • 处理事件,事件停止传递
  • onTouchEvent后续的ACTION_MOVE、ACTION_UP事件继续执行(后续事件会继续分发到该ViewGroup)

onTouchEvent返回false

  • 不处理事件
  • 将事件向上传给父控件的onTouchEvent处理
  • onTouchEvent后续的ACTION_MOVE、ACTION_UP事件不再执行(后续事件将不会分发给该ViewGroup)
  • View的默认实现是不处理事件。所以super.onTouchEvent(event)==false

注意

  • ViewGroup和View的dispatchTouchEvent和onTouchEvent方法 return false的时候事件都会向上传给父控件的onTouchEvent处理
  • ViewGroup的onInterceptTouchEvent 默认是不拦截的,所以return super.onInterceptTouchEvent()和return false一样
  • View的onTouchEvent默认是不处理事件。所以super.onTouchEvent(event)和false一样
  • ViewGroup要想把事件分发给自己的onTouchEvent,只有返回super.dispatchTouchEvent(event),调用内部onInterceptTouchEvent方法并return true,才会调用自己的onTouchEvent方法。其他方法都不行
  • View要想把事件分发给自己的onTouchEvent,只有返回super.dispatchTouchEvent(event),才会调用自己的onTouchEvent方法,其他方法都不行

示例结果分析

全是默认返回值,点击一下

11-14 16:06:18.787 29278-29278/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-down11-14 16:06:18.788 29278-29278/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-down11-14 16:06:18.788 29278-29278/com.cn.liuyz.javademo D/test: MyLinearLayout-onInterceptTouchEvent-down11-14 16:06:18.788 29278-29278/com.cn.liuyz.javademo D/test: MyButton-dispatchTouchEvent-down11-14 16:06:18.788 29278-29278/com.cn.liuyz.javademo D/test: MyButton-onTouchEvent-down11-14 16:06:18.788 29278-29278/com.cn.liuyz.javademo D/test: MyLinearLayout-onTouchEvent-down11-14 16:06:18.791 29278-29278/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-down11-14 16:06:18.844 29278-29278/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:06:18.844 29278-29278/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-move11-14 16:06:18.861 29278-29278/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:06:18.861 29278-29278/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-move11-14 16:06:18.944 29278-29278/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-up11-14 16:06:18.944 29278-29278/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-up

默认情况下事件传递
从Activity –> ViewGroup(MyLinearLayout) –> View(MyButton),从上往下调用dispatchTouchEvent()
再由View(MyButton) –> ViewGroup(MyLinearLayout) –> Activity,从下往上调用onTouchEvent()

注意
同一个事件序列中同一个ViewGroup的onInterceptTouchEvent方法只会调用一次

1、如果在MyLinearLayout的dispatchTouchEvent中返回true

11-14 16:30:44.311 32234-32234/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-down11-14 16:30:44.312 32234-32234/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-down11-14 16:30:44.351 32234-32234/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:30:44.351 32234-32234/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-move11-14 16:30:44.368 32234-32234/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:30:44.368 32234-32234/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-move11-14 16:30:44.384 32234-32234/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:30:44.384 32234-32234/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-move11-14 16:30:44.441 32234-32234/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-up11-14 16:30:44.441 32234-32234/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-up
  • 消费事件,事件不会往下传递
  • dispatchTouchEvent的ACTION_MOVE、ACTION_UP事件继续执行(后续事件会继续分发到该ViewGroup)

2、如果在MyLinearLayout的dispatchTouchEvent中返回false

11-14 16:32:42.088 32717-32717/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-down11-14 16:32:42.089 32717-32717/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-down11-14 16:32:42.092 32717-32717/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-down11-14 16:32:42.136 32717-32717/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:32:42.136 32717-32717/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-move11-14 16:32:42.152 32717-32717/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:32:42.152 32717-32717/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-move11-14 16:32:42.169 32717-32717/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:32:42.169 32717-32717/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-move11-14 16:32:42.201 32717-32717/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-up11-14 16:32:42.201 32717-32717/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-up
  • 不消费事件,事件停止传递
  • 将事件向上传给父控件的onTouchEvent处理
  • dispatchTouchEvent的ACTION_MOVE、ACTION_UP事件不再执行(后续事件将不会分发给该ViewGroup)

3、如果在MyLinearLayout的onInterceptTouchEvent中返回true

11-14 16:36:09.430 880-880/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-down11-14 16:36:09.431 880-880/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-down11-14 16:36:09.431 880-880/com.cn.liuyz.javademo D/test: MyLinearLayout-onInterceptTouchEvent-down11-14 16:36:09.431 880-880/com.cn.liuyz.javademo D/test: MyLinearLayout-onTouchEvent-down11-14 16:36:09.437 880-880/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-down11-14 16:36:09.519 880-880/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:36:09.520 880-880/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-move11-14 16:36:09.526 880-880/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:36:09.527 880-880/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-move11-14 16:36:09.528 880-880/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-up11-14 16:36:09.528 880-880/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-up
  • 不拦截事件,事件继续往下传递
  • onInterceptTouchEvent的ACTION_MOVE、ACTION_UP事件不再执行
  • 同一个事件序列中同一个ViewGroup的onInterceptTouchEvent方法只会调用一次

4、如果在MyLinearLayout的onInterceptTouchEvent中返回true、onTouchEvent中返回true

11-14 16:41:08.186 1143-1143/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-down11-14 16:41:08.188 1143-1143/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-down11-14 16:41:08.188 1143-1143/com.cn.liuyz.javademo D/test: MyLinearLayout-onInterceptTouchEvent-down11-14 16:41:08.189 1143-1143/com.cn.liuyz.javademo D/test: MyLinearLayout-onTouchEvent-down11-14 16:41:08.259 1143-1143/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:41:08.259 1143-1143/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-move11-14 16:41:08.259 1143-1143/com.cn.liuyz.javademo D/test: MyLinearLayout-onTouchEvent-move11-14 16:41:08.276 1143-1143/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:41:08.276 1143-1143/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-move11-14 16:41:08.276 1143-1143/com.cn.liuyz.javademo D/test: MyLinearLayout-onTouchEvent-move11-14 16:41:08.292 1143-1143/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:41:08.292 1143-1143/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-move11-14 16:41:08.293 1143-1143/com.cn.liuyz.javademo D/test: MyLinearLayout-onTouchEvent-move11-14 16:41:08.343 1143-1143/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-up11-14 16:41:08.343 1143-1143/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-up11-14 16:41:08.343 1143-1143/com.cn.liuyz.javademo D/test: MyLinearLayout-onTouchEvent-up
  • 不拦截事件,事件继续往下传递
  • onInterceptTouchEvent的ACTION_MOVE、ACTION_UP事件不再执行
  • 同一个事件序列中同一个ViewGroup的onInterceptTouchEvent方法只会调用一次

注意
ViewGroup 想把事件分发给自己的onTouchEvent,需要拦截器onInterceptTouchEvent方法return true 把事件拦截下来。

5、如果在MyLinearLayout的onInterceptTouchEvent中返回false

11-14 16:44:38.127 1534-1534/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-down11-14 16:44:38.127 1534-1534/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-down11-14 16:44:38.127 1534-1534/com.cn.liuyz.javademo D/test: MyLinearLayout-onInterceptTouchEvent-down11-14 16:44:38.127 1534-1534/com.cn.liuyz.javademo D/test: MyButton-dispatchTouchEvent-down11-14 16:44:38.128 1534-1534/com.cn.liuyz.javademo D/test: MyButton-onTouchEvent-down11-14 16:44:38.128 1534-1534/com.cn.liuyz.javademo D/test: MyLinearLayout-onTouchEvent-down11-14 16:44:38.129 1534-1534/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-down11-14 16:44:38.182 1534-1534/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:44:38.182 1534-1534/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-move11-14 16:44:38.199 1534-1534/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:44:38.199 1534-1534/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-move11-14 16:44:38.223 1534-1534/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-up11-14 16:44:38.224 1534-1534/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-up
  • 拦截事件,事件不会往下传递
  • 传递给自己的onTouchEvent处理
  • onInterceptTouchEvent的ACTION_MOVE、ACTION_UP事件不再执行

注意
ViewGroup的拦截器onInterceptTouchEvent 默认是不拦截的,所以return super.onInterceptTouchEvent()=return false

6、如果在MyLinearLayout的onTouchEvent中返回true

11-14 16:46:08.074 1884-1884/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-down11-14 16:46:08.075 1884-1884/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-down11-14 16:46:08.075 1884-1884/com.cn.liuyz.javademo D/test: MyLinearLayout-onInterceptTouchEvent-down11-14 16:46:08.075 1884-1884/com.cn.liuyz.javademo D/test: MyButton-dispatchTouchEvent-down11-14 16:46:08.076 1884-1884/com.cn.liuyz.javademo D/test: MyButton-onTouchEvent-down11-14 16:46:08.076 1884-1884/com.cn.liuyz.javademo D/test: MyLinearLayout-onTouchEvent-down11-14 16:46:08.140 1884-1884/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:46:08.141 1884-1884/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-move11-14 16:46:08.141 1884-1884/com.cn.liuyz.javademo D/test: MyLinearLayout-onTouchEvent-move11-14 16:46:08.157 1884-1884/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:46:08.157 1884-1884/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-move11-14 16:46:08.157 1884-1884/com.cn.liuyz.javademo D/test: MyLinearLayout-onTouchEvent-move11-14 16:46:08.174 1884-1884/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:46:08.174 1884-1884/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-move11-14 16:46:08.174 1884-1884/com.cn.liuyz.javademo D/test: MyLinearLayout-onTouchEvent-move11-14 16:46:08.241 1884-1884/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-up11-14 16:46:08.241 1884-1884/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-up11-14 16:46:08.241 1884-1884/com.cn.liuyz.javademo D/test: MyLinearLayout-onTouchEvent-up
  • 不消费事件,事件继续往上传递
  • onTouchEvent后续的ACTION_MOVE、ACTION_UP事件不再执行(后续事件会继续分发到该ViewGroup)

7、如果在MyLinearLayout的onTouchEvent中返回false

11-14 16:48:34.671 2190-2190/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-down11-14 16:48:34.672 2190-2190/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-down11-14 16:48:34.672 2190-2190/com.cn.liuyz.javademo D/test: MyLinearLayout-onInterceptTouchEvent-down11-14 16:48:34.672 2190-2190/com.cn.liuyz.javademo D/test: MyButton-dispatchTouchEvent-down11-14 16:48:34.673 2190-2190/com.cn.liuyz.javademo D/test: MyButton-onTouchEvent-down11-14 16:48:34.674 2190-2190/com.cn.liuyz.javademo D/test: MyLinearLayout-onTouchEvent-down11-14 16:48:34.676 2190-2190/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-down11-14 16:48:34.785 2190-2190/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:48:34.785 2190-2190/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-move11-14 16:48:34.802 2190-2190/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:48:34.802 2190-2190/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-move11-14 16:48:34.819 2190-2190/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:48:34.820 2190-2190/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-move11-14 16:48:34.867 2190-2190/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-up11-14 16:48:34.867 2190-2190/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-up
  • 不处理事件,传递给父控件onTouchEvent处理
  • onTouchEvent的ACTION_MOVE、ACTION_UP事件不再执行(后续事件将不会分发给该ViewGroup)

8、如果在MyButton的dispatchTouchEvent中返回true

11-14 16:50:14.361 2408-2408/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-down11-14 16:50:14.361 2408-2408/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-down11-14 16:50:14.362 2408-2408/com.cn.liuyz.javademo D/test: MyLinearLayout-onInterceptTouchEvent-down11-14 16:50:14.362 2408-2408/com.cn.liuyz.javademo D/test: MyButton-dispatchTouchEvent-down11-14 16:50:14.458 2408-2408/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:50:14.458 2408-2408/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-move11-14 16:50:14.458 2408-2408/com.cn.liuyz.javademo D/test: MyLinearLayout-onInterceptTouchEvent-move11-14 16:50:14.458 2408-2408/com.cn.liuyz.javademo D/test: MyButton-dispatchTouchEvent-move11-14 16:50:14.474 2408-2408/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:50:14.474 2408-2408/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-move11-14 16:50:14.474 2408-2408/com.cn.liuyz.javademo D/test: MyLinearLayout-onInterceptTouchEvent-move11-14 16:50:14.475 2408-2408/com.cn.liuyz.javademo D/test: MyButton-dispatchTouchEvent-move11-14 16:50:14.491 2408-2408/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:50:14.491 2408-2408/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-move11-14 16:50:14.491 2408-2408/com.cn.liuyz.javademo D/test: MyLinearLayout-onInterceptTouchEvent-move11-14 16:50:14.491 2408-2408/com.cn.liuyz.javademo D/test: MyButton-dispatchTouchEvent-move11-14 16:50:14.549 2408-2408/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-up11-14 16:50:14.549 2408-2408/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-up11-14 16:50:14.549 2408-2408/com.cn.liuyz.javademo D/test: MyLinearLayout-onInterceptTouchEvent-up11-14 16:50:14.549 2408-2408/com.cn.liuyz.javademo D/test: MyButton-dispatchTouchEvent-up
  • 消费事件,事件不会往下传递
  • dispatchTouchEvent的ACTION_MOVE、ACTION_UP事件继续执行(后续事件会继续分发到该View)

9、如果在MyButton的dispatchTouchEvent中返回false

11-14 16:53:13.553 2734-2734/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-down11-14 16:53:13.554 2734-2734/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-down11-14 16:53:13.555 2734-2734/com.cn.liuyz.javademo D/test: MyLinearLayout-onInterceptTouchEvent-down11-14 16:53:13.555 2734-2734/com.cn.liuyz.javademo D/test: MyButton-dispatchTouchEvent-down11-14 16:53:13.555 2734-2734/com.cn.liuyz.javademo D/test: MyLinearLayout-onTouchEvent-down11-14 16:53:13.558 2734-2734/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-down11-14 16:53:13.726 2734-2734/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:53:13.726 2734-2734/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-move11-14 16:53:13.733 2734-2734/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:53:13.733 2734-2734/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-move11-14 16:53:13.734 2734-2734/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-up11-14 16:53:13.734 2734-2734/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-up
  • 不消费事件
  • 将事件向上传给父控件的onTouchEvent处理
  • dispatchTouchEvent的ACTION_MOVE、ACTION_UP事件不再执行(后续事件将不会分发给该View)

注意
View 没有拦截器,为了让View可以把事件分发给自己的onTouchEvent,View的dispatchTouchEvent默认实现(super)就是把事件分发给自己的onTouchEvent

10、如果在MyButton的onTouchEvent中返回true

11-14 16:55:08.718 2992-2992/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-down11-14 16:55:08.718 2992-2992/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-down11-14 16:55:08.720 2992-2992/com.cn.liuyz.javademo D/test: MyLinearLayout-onInterceptTouchEvent-down11-14 16:55:08.720 2992-2992/com.cn.liuyz.javademo D/test: MyButton-dispatchTouchEvent-down11-14 16:55:08.720 2992-2992/com.cn.liuyz.javademo D/test: MyButton-onTouchEvent-down11-14 16:55:08.807 2992-2992/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:55:08.807 2992-2992/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-move11-14 16:55:08.807 2992-2992/com.cn.liuyz.javademo D/test: MyLinearLayout-onInterceptTouchEvent-move11-14 16:55:08.807 2992-2992/com.cn.liuyz.javademo D/test: MyButton-dispatchTouchEvent-move11-14 16:55:08.807 2992-2992/com.cn.liuyz.javademo D/test: MyButton-onTouchEvent-move11-14 16:55:08.823 2992-2992/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:55:08.823 2992-2992/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-move11-14 16:55:08.823 2992-2992/com.cn.liuyz.javademo D/test: MyLinearLayout-onInterceptTouchEvent-move11-14 16:55:08.823 2992-2992/com.cn.liuyz.javademo D/test: MyButton-dispatchTouchEvent-move11-14 16:55:08.824 2992-2992/com.cn.liuyz.javademo D/test: MyButton-onTouchEvent-move11-14 16:55:08.867 2992-2992/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-up11-14 16:55:08.867 2992-2992/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-up11-14 16:55:08.867 2992-2992/com.cn.liuyz.javademo D/test: MyLinearLayout-onInterceptTouchEvent-up11-14 16:55:08.867 2992-2992/com.cn.liuyz.javademo D/test: MyButton-dispatchTouchEvent-up11-14 16:55:08.867 2992-2992/com.cn.liuyz.javademo D/test: MyButton-onTouchEvent-up
  • 处理事件,事件停止传递
  • onTouchEvent后续的ACTION_MOVE、ACTION_UP事件继续执行(后续事件会继续分发到该ViewGroup)

11、如果在MyButton的onTouchEvent中返回false

11-14 16:56:37.628 3205-3205/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-down11-14 16:56:37.628 3205-3205/com.cn.liuyz.javademo D/test: MyLinearLayout-dispatchTouchEvent-down11-14 16:56:37.628 3205-3205/com.cn.liuyz.javademo D/test: MyLinearLayout-onInterceptTouchEvent-down11-14 16:56:37.629 3205-3205/com.cn.liuyz.javademo D/test: MyButton-dispatchTouchEvent-down11-14 16:56:37.629 3205-3205/com.cn.liuyz.javademo D/test: MyButton-onTouchEvent-down11-14 16:56:37.629 3205-3205/com.cn.liuyz.javademo D/test: MyLinearLayout-onTouchEvent-down11-14 16:56:37.631 3205-3205/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-down11-14 16:56:37.718 3205-3205/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:56:37.718 3205-3205/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-move11-14 16:56:37.735 3205-3205/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-move11-14 16:56:37.735 3205-3205/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-move11-14 16:56:37.784 3205-3205/com.cn.liuyz.javademo D/test: Activity-dispatchTouchEvent-up11-14 16:56:37.784 3205-3205/com.cn.liuyz.javademo D/test: Activity-onTouchEvent-up
  • 不处理事件
  • 将事件向上传给父控件的onTouchEvent处理
  • onTouchEvent后续的ACTION_MOVE、ACTION_UP事件不再执行(后续事件将不会分发给该ViewGroup)
  • View的默认实现是不消费的。所以super==false

onTouch和onTouchEvent区别和使用

这两个方法都是在View的dispatchTouchEvent中调用,onTouch优先于onTouchEvent执行。如果在onTouch方法中通过返回true将事件消费掉,onTouchEvent将不会执行。

onTouch能执行需要两个条件,第一mOnTouchListener值不能为空,第二当前点击的控件必须是enable。因此如果控件是非enable的,那么给它注册onTouch事件将永远得不到执行。对于这一类控件,如果我们想要监听它的touch事件,就必须通过在该控件中重写onTouchEvent方法来实现。

原创粉丝点击