Android事件传递

来源:互联网 发布:蓄水池抽样算法 编辑:程序博客网 时间:2024/06/05 18:08
事件传递主要有以下的调用顺序 dispatchTouchEvent -->  onInterceptTouchEvent--> onTouchEvent 
一、主要用到以下几个事件
(1)public boolean dispatchTouchEvent(MotionEvent ev) : 主要做事件分发的作用,源码中会调用到了onInterceptTouchEvent()和onTouchEvent() 用于去判断事件是否需要分发;
  当返回值为false时则表示此事件不做分发, dispatchTouchEvent 调用完后不再走下面的onInterceptTouchEvent   ,onTouchEvent ,为true时则根据 onInterceptTouchEvent ,onTouchEvent 去分发事件,走以下调用顺序 :dispatchTouchEvent -->  onInterceptTouchEvent--> onTouchEvent ;
(2)public boolean onInterceptTouchEvent(MotionEvent ev) :事件拦截,主要是用于拦截事件是否向下传递,当返回为false时,则事件往下传递,当返回为true时,事件则不向下传递。(继承与ViewGroup的子类才有改方法,继承于View的之类则没有此方法)
(3) public boolean onTouchEvent(MotionEvent event) : 事件消化,如果返回为true时则事件被消化掉,不再向父传递,若果返回为false则向父view传递



二、进行如下实验 ,写了三个自定义事件,继承于LinearLayout ,分别都重写他的三个事件传递方法;
public class MyView2 extends LinearLayout {

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

@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d("MyView0", "MyView2 onTouchEvent eventType = " + event.getAction() + " eventX = " + event.getX() + " eventY = " + event.getY());
return super.onTouchEvent(event);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.d("MyView0","MyView2 onInterceptTouchEvent eventType = "+ev.getAction()+" eventX = "+ev.getX()+" eventY = "+ev.getY());
return super.onInterceptTouchEvent(ev);
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.d("MyView0","MyView2 dispatchTouchEvent eventType = "+ev.getAction()+" eventX = "+ev.getX()+" eventY = "+ev.getY());
return super.dispatchTouchEvent(ev);
}
}
(1)、页面布局如下:
<?xml version="1.0" encoding="utf-8"?>
<com.prj.test.yan.eventTranslate.utils.MyView0
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="#ffffff"
android:orientation="vertical">
>
<com.prj.test.yan.eventTranslate.utils.MyView1
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="50dp"
android:background="#538CCC"
android:id="@+id/myView1"
android:orientation="vertical"
>
<com.prj.test.yan.eventTranslate.utils.MyView2
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="50dp"
android:background="#2CA748"
android:id="@+id/myView2"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="测试"/>
</com.prj.test.yan.eventTranslate.utils.MyView2>
</com.prj.test.yan.eventTranslate.utils.MyView1>
</com.prj.test.yan.eventTranslate.utils.MyView0>
(2)进行以下实验:
 a、在事件分发(dispatchTouchEvent)方法中拦截 :
1、MyView0 中返回false,则事件不再调用 onInterceptTouchEvent--> onTouchEvent ,点击任何部分都只拦截到了MyView0 的事件,不再往包裹的子view传递;
    @Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.d("MyView0","MyView0 dispatchTouchEvent eventType = "+ev.getAction()+" eventX = "+ev.getX()+" eventY = "+ev.getY());
return false;
// return super.dispatchTouchEvent(ev);

}
结果:
07-28 15:06:27.305  11933-11933/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 dispatchTouchEvent eventType = 0 eventX = 75.89459 eventY = 763.2896
07-28 15:06:28.313  11933-11933/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 dispatchTouchEvent eventType = 0 eventX = 153.7864 eventY = 759.2927
07-28 15:06:29.073  11933-11933/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 dispatchTouchEvent eventType = 0 eventX = 289.59778 eventY = 752.2982
2、MyView1 返回false
07-28 15:11:25.130  13289-13289/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 dispatchTouchEvent eventType = 0 eventX = 152.7878 eventY = 725.3193
07-28 15:11:25.130  13289-13289/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 onInterceptTouchEvent eventType = 0 eventX = 152.7878 eventY = 725.3193
07-28 15:11:25.130  13289-13289/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView1 dispatchTouchEvent eventType = 0 eventX = 52.787796 eventY = 625.3193
07-28 15:11:25.130  13289-13289/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 onTouchEvent eventType = 0 eventX = 152.7878 eventY = 725.3193

b、在onInterceptTouchEvent 中拦截
1、返回为true时则事件不再往子view传递
 
点击MyView0 的日志:
07-28 15:19:01.544  13700-13700/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 dispatchTouchEvent eventType = 0 eventX = 36.948685 eventY = 814.2498
07-28 15:19:01.544  13700-13700/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 onInterceptTouchEvent eventType = 0 eventX = 36.948685 eventY = 814.2498
07-28 15:19:01.544  13700-13700/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 onTouchEvent eventType = 0 eventX = 36.948685 eventY = 814.2498
点击MyView1 的日志:
07-28 15:20:05.999  13700-13700/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 dispatchTouchEvent eventType = 0 eventX = 183.7448 eventY = 633.3911
07-28 15:20:05.999  13700-13700/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 onInterceptTouchEvent eventType = 0 eventX = 183.7448 eventY = 633.3911
07-28 15:20:05.999  13700-13700/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 onTouchEvent eventType = 0 eventX = 183.7448 eventY = 633.3911
点击MyView2 的日志:
07-28 15:20:26.643  13700-13700/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 dispatchTouchEvent eventType = 0 eventX = 290.5964 eventY = 655.3739
07-28 15:20:26.643  13700-13700/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 onInterceptTouchEvent eventType = 0 eventX = 290.5964 eventY = 655.3739
07-28 15:20:26.643  13700-13700/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 onTouchEvent eventType = 0 eventX = 290.5964 eventY = 655.3739
1、返回为false时则事件往子view传递
点击MyView0的日志:
07-28 15:23:33.009  14150-14150/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 dispatchTouchEvent eventType = 0 eventX = 33.952843 eventY = 795.26465
07-28 15:23:33.009  14150-14150/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 onInterceptTouchEvent eventType = 0 eventX = 33.952843 eventY = 795.26465
07-28 15:23:33.009  14150-14150/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 onTouchEvent eventType = 0 eventX = 33.952843 eventY = 795.26465
点击MyView1的日志:
07-28 15:23:57.900  14150-14150/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 dispatchTouchEvent eventType = 0 eventX = 158.77948 eventY = 901.1819
07-28 15:23:57.900  14150-14150/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 onInterceptTouchEvent eventType = 0 eventX = 158.77948 eventY = 901.1819
07-28 15:23:57.900  14150-14150/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView1 dispatchTouchEvent eventType = 0 eventX = 58.77948 eventY = 801.1819
07-28 15:23:57.900  14150-14150/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView1 onInterceptTouchEvent eventType = 0 eventX = 58.77948 eventY = 801.1819
07-28 15:23:57.900  14150-14150/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView1 onTouchEvent eventType = 0 eventX = 58.77948 eventY = 801.1819
07-28 15:23:57.900  14150-14150/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 onTouchEvent eventType = 0 eventX = 158.77948 eventY = 901.1819
 
c、onTouchEvent 事件消化
1、当onTouchEvent 返回值为true 时则消化掉改事件,事件不再往上的父view传递
点击MyView1
07-28 15:38:32.993  15091-15091/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 dispatchTouchEvent eventType = 0 eventX = 165.76978 eventY = 715.3271
07-28 15:38:32.993  15091-15091/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 onInterceptTouchEvent eventType = 0 eventX = 165.76978 eventY = 715.3271
07-28 15:38:32.993  15091-15091/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView1 dispatchTouchEvent eventType = 0 eventX = 65.769775 eventY = 615.3271
07-28 15:38:32.993  15091-15091/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView1 onInterceptTouchEvent eventType = 0 eventX = 65.769775 eventY = 615.3271
07-28 15:38:32.993  15091-15091/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView1 onTouchEvent eventType = 0 eventX = 65.769775 eventY = 615.3271
07-28 15:38:33.133  15091-15091/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 onInterceptTouchEvent eventType = 1 eventX = 165.76978 eventY = 715.3271
07-28 15:38:33.133  15091-15091/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView1 dispatchTouchEvent eventType = 1 eventX = 65.769775 eventY = 615.3271
07-28 15:38:33.133  15091-15091/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView1 onTouchEvent eventType = 1 eventX = 65.769775 eventY = 615.3271
07-28 15:38:33.133  15091-15091/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 dispatchTouchEvent eventType = 1 eventX = 165.76978 eventY = 715.3271
2、当onTouchEvent 返回值为false时则不消化掉改事件,事件往上的父view传递
点击MyView2 
07-28 15:45:20.928  15866-15866/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 dispatchTouchEvent eventType = 0 eventX = 335.534 eventY = 554.45276
07-28 15:45:20.928  15866-15866/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 onInterceptTouchEvent eventType = 0 eventX = 335.534 eventY = 554.45276
07-28 15:45:20.928  15866-15866/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView1 dispatchTouchEvent eventType = 0 eventX = 235.534 eventY = 454.45276
07-28 15:45:20.928  15866-15866/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView1 onInterceptTouchEvent eventType = 0 eventX = 235.534 eventY = 454.45276
07-28 15:45:20.928  15866-15866/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView2 dispatchTouchEvent eventType = 0 eventX = 135.534 eventY = 354.45276
07-28 15:45:20.928  15866-15866/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView2 onInterceptTouchEvent eventType = 0 eventX = 135.534 eventY = 354.45276
07-28 15:45:20.928  15866-15866/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView2 onTouchEvent eventType = 0 eventX = 135.534 eventY = 354.45276
07-28 15:45:20.928  15866-15866/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView1 onTouchEvent eventType = 0 eventX = 235.534 eventY = 454.45276
07-28 15:45:20.928  15866-15866/com.prj.test.yan.eventTranslate D/MyView0﹕ MyView0 onTouchEvent eventType = 0 eventX = 335.534 eventY = 554.45276
总结如下:借用以下别人博文的两张图
 

dispatchTouchEvent ,onInterceptTouchEvent 主要用于事件的向下传递,


 

0 0
原创粉丝点击