事件分发机制是Android中卓殊主要的二个知识点

示例二、在示例一的底子上,让View的onTouch伊芙nt不消耗事件时的传递流程

接下去让地点的EventDispatchTestView的onTouchEvent重临false:

@Override
public boolean onTouchEvent(MotionEvent event) {
    Log.i(TAG, "onTouchEvent: " + event.getAction() + " | 是否消耗事件:" + false);
    return false;//super.onTouchEvent(event);
}

测试log如下:

01-05 18:18:52.545 10771-10771/cn.codingblock.view I/Activity: dispatchTouchEvent: 0 | 分发事件
01-05 18:18:52.545 10771-10771/cn.codingblock.view I/——Layout: dispatchTouchEvent: 0 | 分发事件
01-05 18:18:52.546 10771-10771/cn.codingblock.view I/——Layout: onInterceptTouchEvent: 0 | 是否拦截:false
01-05 18:18:52.546 10771-10771/cn.codingblock.view I/————View: dispatchTouchEvent: 0 | 分发事件
01-05 18:18:52.546 10771-10771/cn.codingblock.view I/————View: onTouchEvent: 0 | 是否消耗事件:false
01-05 18:18:52.546 10771-10771/cn.codingblock.view I/——Layout: onTouchEvent: 0 | 是否消耗事件:false
01-05 18:18:52.547 10771-10771/cn.codingblock.view I/Activity: onTouchEvent: 0 | 是否消耗事件:true

01-05 18:18:52.629 10771-10771/cn.codingblock.view I/Activity: dispatchTouchEvent: 2 | 分发事件
01-05 18:18:52.629 10771-10771/cn.codingblock.view I/Activity: onTouchEvent: 2 | 是否消耗事件:true

01-05 18:18:52.630 10771-10771/cn.codingblock.view I/Activity: dispatchTouchEvent: 1 | 分发事件
01-05 18:18:52.630 10771-10771/cn.codingblock.view I/Activity: onTouchEvent: 1 | 是否消耗事件:true

当View的onTouchEvent不消耗事件时,事件会交到ViewGroup的onTouch伊夫nt方法管理,而从log能够见到ViewGroup的onTouchEvent暗中认可也不消耗事件,所以事件由提交Activity的onTouchEvent方法管理,最后事件流的后续部分不再传递给ViewGroup和View,而是径直传送给Activity的onTouchEvent管理。

示例三、在示例二的根基上让ViewGroup消耗事件

修改伊夫ntDispatchLinearLayout的onTouch伊芙nt(),让其归来true。

@Override
public boolean onTouchEvent(MotionEvent event) {
    Log.i(TAG, "onTouchEvent: " + event.getAction() + " | 是否消耗事件:" + true);
    return true;//super.onTouchEvent(event);
}

测试log如下:

01-05 18:34:53.409 21169-21169/cn.codingblock.view I/Activity: dispatchTouchEvent: 0 | 分发事件
01-05 18:34:53.409 21169-21169/cn.codingblock.view I/——Layout: dispatchTouchEvent: 0 | 分发事件
01-05 18:34:53.409 21169-21169/cn.codingblock.view I/——Layout: onInterceptTouchEvent: 0 | 是否拦截:false
01-05 18:34:53.409 21169-21169/cn.codingblock.view I/————View: dispatchTouchEvent: 0 | 分发事件
01-05 18:34:53.410 21169-21169/cn.codingblock.view I/————View: onTouchEvent: 0 | 是否消耗事件:false
01-05 18:34:53.410 21169-21169/cn.codingblock.view I/——Layout: onTouchEvent: 0 | 是否消耗事件:true

01-05 18:34:53.420 21169-21169/cn.codingblock.view I/Activity: dispatchTouchEvent: 2 | 分发事件
01-05 18:34:53.420 21169-21169/cn.codingblock.view I/——Layout: dispatchTouchEvent: 2 | 分发事件
01-05 18:34:53.420 21169-21169/cn.codingblock.view I/——Layout: onTouchEvent: 2 | 是否消耗事件:true

01-05 18:34:53.470 21169-21169/cn.codingblock.view I/Activity: dispatchTouchEvent: 1 | 分发事件
01-05 18:34:53.470 21169-21169/cn.codingblock.view I/——Layout: dispatchTouchEvent: 1 | 分发事件
01-05 18:34:53.470 21169-21169/cn.codingblock.view I/——Layout: onTouchEvent: 1 | 是否消耗事件:true

此种景况下,事件流的ACTION_DOWN先达到View的onTouchEvent,开采它不消耗事件,继而重临上级的ViewGroup的onTouch伊芙nt中,开采它要开支事件,事件流的持续部分就不在传递给View,也不在调用ViewGroup的onInterceptTouchEvent方法,因为已经明白View不处总管件,所以没须求再经过onInterceptTouch伊芙nt方法来判别了。

小结

为了更加好的了然,可以把事件流看成是一队人,把ACTION_DOWN类型看做探路人,探路人按规定的路径先走一遍,直到走到View的onTouch伊芙nt这里,借使onTouchEvent重临true,可领略成此路通,后续部队能够苏醒。如果回到false,能够清楚成此路不通,然后探路人再到Layout(ViewGroup)的onTouch伊芙nt中问路通不通,若是通的话后续部队就不要再去View这里了,直接到ViewGroup那来就能够了。而一旦ViewGroup这里路也打断,那么探路人就不得不去Activity的onTouch伊夫nt这里了,后续部队也平素去Activity的onTouch伊夫nt这里就足以了。


最后想说的是,本连串文章为博主对Android知识进行再一次梳理,查缺补漏的上学进度,一方面是对友好忘记的事物加以复习重新驾驭,另一方面相信在重新学习的进度中定会有高大的新获得,要是你也会有跟自个儿同一的主见,无妨关注本人一块读书,相互商讨,共同升高!

参谋文献:

  • 《Android开拓形式查究》

dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent

  • boolean dispatchTouchEvent (MotionEvent event):

分发事件,只要事件能传递到如今View就必定会调用此办法,其再次回到值是二个布尔类型表示是或不是消耗事件。重临true代表消耗事件,事件流的承袭部分还有也许会随之传递过来;再次回到false代表不消耗事件,事件流的后续部分就不再传递于此。

  • boolean onInterceptTouchEvent (MotionEvent ev):

此情势表示是不是拦截Motion伊芙nt事件,唯有ViewGroup类型的控件才有此方法。假使此方法重临true表示拦截事件,事件将传递给当下View的onTouch伊夫nt()方法,而不再向其下属的View传递。要是此情势再次来到false表示不阻碍事件,事件将传递给下级View的dispatchTouch伊芙nt()。

  • boolean onTouchEvent (MotionEvent event):

此格局用来管理Motion伊芙nt,再次来到值表示是还是不是消耗事件。重返true表示消耗事件,那么事件流的存在延续部分还或者会传递过来;重临false表示不消耗事件,事件将交给上级View的onTouch伊夫nt()管理,假使上级View的onTouch伊芙nt()依然再次回到false,那么事件将再付诸上级的上司管理,依此类推,倘使各级View的onTouch伊夫nt()都不消耗事件,那么事件最终将交由Activity的onTouchEvent()管理。

上文说了这么多照旧相当不够具体,先用流程图轮廓说多美滋个以上三个点子的涉嫌,及调用流程,下文还恐怕会构成具体示例详细表达在事件分发传递中逐条艺术的调用准绳。

三者关系大要如下图:

图片 1

示例五、给View绑定OnTouchListener和OnClickListener监听器。

在EventDispatchActivity的onCreate()方法里面增多如下代码,并将EventDispatchLinearLayout和伊芙ntDispatchTestView的各艺术的再次回到值都还原成示例一中的状态。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_event_dispatch);
    edtv_test = ViewUtils.find(this, R.id.edtv_test);
    edll_test = ViewUtils.find(this, R.id.edll_test);

    edtv_test.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // 为了log显示的层次更加清晰,这里的TAG使用View的TAG
            Log.i("————View", "onTouch: 返回 " + false);
            return false;
        }
    });

    edtv_test.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // 为了log显示的层次更加清晰,这里的TAG使用View的TAG
            Log.i("————View", "onClick: ");
        }
    });
}

测试log如下:

01-06 19:35:07.563 6737-6737/cn.codingblock.view I/Activity: dispatchTouchEvent: 0 | 分发事件
01-06 19:35:07.563 6737-6737/cn.codingblock.view I/——Layout: dispatchTouchEvent: 0 | 分发事件
01-06 19:35:07.563 6737-6737/cn.codingblock.view I/——Layout: onInterceptTouchEvent: 0 | 是否拦截:false
01-06 19:35:07.563 6737-6737/cn.codingblock.view I/————View: dispatchTouchEvent: 0 | 分发事件
01-06 19:35:07.563 6737-6737/cn.codingblock.view I/————View: onTouch: 返回 false
01-06 19:35:07.563 6737-6737/cn.codingblock.view I/————View: onTouchEvent: 0 | 是否消耗事件:true

01-06 19:35:07.573 6737-6737/cn.codingblock.view I/Activity: dispatchTouchEvent: 2 | 分发事件
01-06 19:35:07.573 6737-6737/cn.codingblock.view I/——Layout: dispatchTouchEvent: 2 | 分发事件
01-06 19:35:07.573 6737-6737/cn.codingblock.view I/——Layout: onInterceptTouchEvent: 2 | 是否拦截:false
01-06 19:35:07.573 6737-6737/cn.codingblock.view I/————View: dispatchTouchEvent: 2 | 分发事件
01-06 19:35:07.574 6737-6737/cn.codingblock.view I/————View: onTouch: 返回 false
01-06 19:35:07.574 6737-6737/cn.codingblock.view I/————View: onTouchEvent: 2 | 是否消耗事件:true

01-06 19:35:07.673 6737-6737/cn.codingblock.view I/Activity: dispatchTouchEvent: 1 | 分发事件
01-06 19:35:07.674 6737-6737/cn.codingblock.view I/——Layout: dispatchTouchEvent: 1 | 分发事件
01-06 19:35:07.674 6737-6737/cn.codingblock.view I/——Layout: onInterceptTouchEvent: 1 | 是否拦截:false
01-06 19:35:07.674 6737-6737/cn.codingblock.view I/————View: dispatchTouchEvent: 1 | 分发事件
01-06 19:35:07.674 6737-6737/cn.codingblock.view I/————View: onTouch: 返回 false
01-06 19:35:07.674 6737-6737/cn.codingblock.view I/————View: onTouchEvent: 1 | 是否消耗事件:true
01-06 19:35:07.704 6737-6737/cn.codingblock.view I/————View: onClick: 

下一场再上边修改代码,让onTouch()方法消耗事件,也正是回去true,再观望log:

edtv_test.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // 为了log显示的层次更加清晰,这里的TAG使用View的TAG
        Log.i("————View", "onTouch: 返回 " + false);
        return false;
    }
});

log如下:

01-07 11:03:55.411 2757-2757/cn.codingblock.view I/Activity: dispatchTouchEvent: 0 | 分发事件
01-07 11:03:55.412 2757-2757/cn.codingblock.view I/——Layout: dispatchTouchEvent: 0 | 分发事件
01-07 11:03:55.412 2757-2757/cn.codingblock.view I/——Layout: onInterceptTouchEvent: 0 | 是否拦截:false
01-07 11:03:55.412 2757-2757/cn.codingblock.view I/————View: dispatchTouchEvent: 0 | 分发事件
01-07 11:03:55.412 2757-2757/cn.codingblock.view I/————View: onTouch: 返回 true

01-07 11:03:55.542 2757-2757/cn.codingblock.view I/Activity: dispatchTouchEvent: 2 | 分发事件
01-07 11:03:55.542 2757-2757/cn.codingblock.view I/——Layout: dispatchTouchEvent: 2 | 分发事件
01-07 11:03:55.542 2757-2757/cn.codingblock.view I/——Layout: onInterceptTouchEvent: 2 | 是否拦截:false
01-07 11:03:55.542 2757-2757/cn.codingblock.view I/————View: dispatchTouchEvent: 2 | 分发事件
01-07 11:03:55.542 2757-2757/cn.codingblock.view I/————View: onTouch: 返回 true

01-07 11:03:55.560 2757-2757/cn.codingblock.view I/Activity: dispatchTouchEvent: 1 | 分发事件
01-07 11:03:55.560 2757-2757/cn.codingblock.view I/——Layout: dispatchTouchEvent: 1 | 分发事件
01-07 11:03:55.560 2757-2757/cn.codingblock.view I/——Layout: onInterceptTouchEvent: 1 | 是否拦截:false
01-07 11:03:55.560 2757-2757/cn.codingblock.view I/————View: dispatchTouchEvent: 1 | 分发事件
01-07 11:03:55.560 2757-2757/cn.codingblock.view I/————View: onTouch: 返回 true

从log中我们得以看出:

  • 为View绑定的OnTouchListener中的onTouch()方法是预先于View的onTouch伊芙nt()方法实行的。假若在onTouch()消耗了平地风波(重临true),那么事件将不在传递给onTouchEvent()方法,最后也不会调用onClick()方法。
  • 为View绑定的OnClickListener中的onClick()方法优先级最低,是在全部事件流停止后才会被调用,也便是须求通过手指的按下–抬起这么些历程才会触发onClick()方法。

示例一,暗中认可情形下的事件传递流程

创办3个类,多少个Activity、贰个承袭自LinearLayout的View,一个持续自Button的View,同样重视写他们的dispatchTouchEvent()、onIntercepteTouch伊夫nt()、onTouchEvent(),三个类及布局文件的代码如下:

  • EventDispatchActivity

/**
 * 事件分发机制测试Activity
 * Created by liuwei on 18/1/5.
 */
public class EventDispatchActivity extends AppCompatActivity {

    private final static String TAG = "Activity";//EventDispatchActivity.class.getSimpleName();

    private EventDispatchTestView edtv_test;
    private EventDispatchLinearLayout edll_test;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_event_dispatch);
        edtv_test = ViewUtils.find(this, R.id.edtv_test);
        edll_test = ViewUtils.find(this, R.id.edll_test);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {

        // 被调用时输出log,event.getAction表示事件的类型,0:ACTION_DOWN,1:ACTION_UP,2:ACTION_MOVE。

        Log.i(TAG, "dispatchTouchEvent: " + event.getAction() + " | 分发事件");
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i(TAG, "onTouchEvent: " + event.getAction() + " | 是否消耗事件:" + true);
        return super.onTouchEvent(event);
    }
}
  • EventDispatchLinearLayout

/**
 * 事件分发机制测试 ViewGroup
 * Created by liuwei on 18/1/5.
 */
public class EventDispatchLinearLayout extends LinearLayout {

    private final static String TAG = "——Layout";//EventDispatchLinearLayout.class.getSimpleName();


    public EventDispatchLinearLayout(Context context) {
        super(context);
    }

    public EventDispatchLinearLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        Log.i(TAG, "dispatchTouchEvent: " + event.getAction() + " | 分发事件");
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        Log.i(TAG, "onInterceptTouchEvent: " + event.getAction() + " | 是否拦截:" + false);
        return super.onInterceptTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i(TAG, "onTouchEvent: " + event.getAction() + " | 是否消耗事件:" + false);
        return super.onTouchEvent(event);
    }
}
  • EventDispatchTestView

/**
 * 事件分发机制测试 View
 * Created by liuwei on 18/1/5.
 */
public class EventDispatchTestView extends Button {

    private final static String TAG = "————View";//EventDistpatchTestView.class.getSimpleName();

    public EventDispatchTestView(Context context) {
        super(context);
    }

    public EventDispatchTestView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        Log.i(TAG, "dispatchTouchEvent: " + event.getAction() + " | 分发事件");
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i(TAG, "onTouchEvent: " + event.getAction() + " | 是否消耗事件:" + true);
        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"
    android:orientation="vertical"
    tools:context="cn.codingblock.view.event_dispatch.EventDispatchActivity">

    <cn.codingblock.view.event_dispatch.EventDispatchLinearLayout
        android:id="@+id/edll_test"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#cccccc">

        <cn.codingblock.view.event_dispatch.EventDispatchTestView
            android:id="@+id/edtv_test"
            android:layout_width="300dp"
            android:layout_height="300dp"
            android:layout_margin="10dp"
            android:background="#000000"/>

    </cn.codingblock.view.event_dispatch.EventDispatchLinearLayout>

</LinearLayout>

运维代码,点击EventDispatchTestView(黑灰区域),log输出如下(log中的数字代表事件的品类,0:ACTION_DOWN,1:ACTION_UP,2:ACTION_MOVE):

01-05 16:58:05.574 23295-23295/cn.codingblock.view I/Activity: dispatchTouchEvent: 0 | 分发事件
01-05 16:58:05.574 23295-23295/cn.codingblock.view I/——Layout: dispatchTouchEvent: 0 | 分发事件
01-05 16:58:05.574 23295-23295/cn.codingblock.view I/——Layout: onInterceptTouchEvent: 0 | 是否拦截:false
01-05 16:58:05.574 23295-23295/cn.codingblock.view I/————View: dispatchTouchEvent: 0 | 分发事件
01-05 16:58:05.574 23295-23295/cn.codingblock.view I/————View: onTouchEvent: 0 | 是否消耗事件:true

01-05 16:58:05.611 23295-23295/cn.codingblock.view I/Activity: dispatchTouchEvent: 2 | 分发事件
01-05 16:58:05.611 23295-23295/cn.codingblock.view I/——Layout: dispatchTouchEvent: 2 | 分发事件
01-05 16:58:05.611 23295-23295/cn.codingblock.view I/——Layout: onInterceptTouchEvent: 2 | 是否拦截:false
01-05 16:58:05.611 23295-23295/cn.codingblock.view I/————View: dispatchTouchEvent: 2 | 分发事件
01-05 16:58:05.611 23295-23295/cn.codingblock.view I/————View: onTouchEvent: 2 | 是否消耗事件:true

01-05 16:58:05.619 23295-23295/cn.codingblock.view I/Activity: dispatchTouchEvent: 1 | 分发事件
01-05 16:58:05.619 23295-23295/cn.codingblock.view I/——Layout: dispatchTouchEvent: 1 | 分发事件
01-05 16:58:05.619 23295-23295/cn.codingblock.view I/——Layout: onInterceptTouchEvent: 1 | 是否拦截:false
01-05 16:58:05.620 23295-23295/cn.codingblock.view I/————View: dispatchTouchEvent: 1 | 分发事件
01-05 16:58:05.620 23295-23295/cn.codingblock.view I/————View: onTouchEvent: 1 | 是否消耗事件:true

由log可以看到ViewGroup的onInterceptTouchEvent方法暗许是不阻拦事件的,View的onTouchEvent方法私下认可消耗事件。事件流的ACTION_DOWN类型Motion
Event率先达到View的onTouch伊夫nt方法中,此时onTouch伊芙nt方法重临true,表示要处管事人件,所以事件流的承继部分照旧通过log中的流程达到了View的onTouchEvent方法中。

哪些是事件分发机制?

说了半天的风浪分发机制那到底是个吗东西吗?大家不用把它想象的那么高深莫测,不要在理念上给和睦设上阻碍,其实很轻巧理解,博主的知晓是:简单的说,事件分发机制即是Android系统对事件传递进度规定的一种事件传递准绳,事件都会遵从这几个准则进行分发传递。

在研商事件分发机制在此以前,我们先来规定一下分析的步骤,化整为零,各种击破:

  • 弄精通深入分析指标:MotionEvent。
  • 摸底多少个章程:dispatchTouch伊芙nt(MotionEvent
    event)、onInterceptTouch伊夫nt(Motion
    event)、onTouchEvent(MotionEvent event)。
  • MotionEvent事件的传递进程
  • 小结

MotionEvent

实质上点击事件的分发进度正是对MotionEvent事件的散发进程,当客户点击操作按下后,Motion伊芙nt事件随后发出并通过自然的准绳传递到钦命的View上,那几个传递的长河和法则便是事件分发机制。

而点击操作触发Motion伊夫nt事件是二个风云流或然说是二个平地风波系列,其优秀的风云类型有如下三种:

  • MotionEvent.ACTION_DOWN:手指刚点下显示屏时接触此类型。
  • MotionEvent.ACTION_MOVE:手指在显示屏上运动时会多次接触此类型。
  • MotionEvent.ACTION_UP:手指在显示屏上抬起时接触此类型。

要非常注意的是,平日状态下一个Motion伊芙nt事件系列包蕴三个 ACTION_DOWN
若干个 ACTION_MOVE 和 ACTION_UP
是二个完全的平地风波系列。(点下来立马抬起指头时,会独有 ACTION_DOWN 和
ACTION_UP,那也是一个平安无事的风云连串)

Motion伊夫nt事件传递进度

当手引导击显示屏发出一个Touch事件后,事件依照Activity->Window->View的顺序依次传递。

第一会传递给Activity的dispatchTouchEvent(),在此格局内部会将由Window管理,接着事件会传递给根View,根View接收到事件后就能够依照事件分发机制去处总管件。

根View在这里正是三个ViewGroup,它在接受到事件后会调用dispatchTouch伊芙nt(),在此办法内部会经过onInterceptTouchEvent()方法剖断是还是不是拦截事件,若是onInterceptTouch伊夫nt()重回true就意味着它要阻拦事件,事件将传递给当下ViewGroup的onTouch伊夫nt()。假若onInterceptTouchEvent()放回false就象征它不阻碍事件,事件将传给其下属的View,调用下级View的dispatchTouchEvent()。

根View的下边View大概又是三个ViewGroup,假如那样的话其传递流程同根View同样。无论根View的部属View是还是不是ViewGroup,尽管不阻碍事件,最后事件会传送到贰个纯View的控件上。

当贰个View(纯View控件)接收到事件后,也会调用其dispatchTouch伊芙nt(),然后在此格局内部会调用当前View的onTouch伊夫nt(),如果onTouchEvent()再次来到true则意味要管理这事件。借使回到false表示不消耗事件,其上边View的onTouch伊芙nt()将被调用,则事件流的继续部分不再传递到近期View,在贰个事件流中也不会再调用当前View的dispatchTouch伊夫nt()。

接下去通超过实际际示例来查看事件传递的流水线:

示例四、假使在ViewGroup的onInterceptTouch伊芙nt中回到了true拦截了平地风波,整个事件将不再传递给View而是直接交由ViewGroup的onTouch伊夫nt管理。

修改伊夫ntDispatchLinearLayout的onInterceptTouchEvent(),让其回来true。

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    Log.i(TAG, "onInterceptTouchEvent: " + event.getAction() + " | 是否拦截:" + true);
    return true;//super.onInterceptTouchEvent(event);
}

测试log如下:

01-05 19:03:21.788 9733-9733/cn.codingblock.view I/Activity: dispatchTouchEvent: 0 | 分发事件
01-05 19:03:21.789 9733-9733/cn.codingblock.view I/——Layout: dispatchTouchEvent: 0 | 分发事件
01-05 19:03:21.789 9733-9733/cn.codingblock.view I/——Layout: onInterceptTouchEvent: 0 | 是否拦截:true
01-05 19:03:21.789 9733-9733/cn.codingblock.view I/——Layout: onTouchEvent: 0 | 是否消耗事件:true
01-05 19:03:21.819 9733-9733/cn.codingblock.view I/Activity: dispatchTouchEvent: 2 | 分发事件
01-05 19:03:21.819 9733-9733/cn.codingblock.view I/——Layout: dispatchTouchEvent: 2 | 分发事件
01-05 19:03:21.819 9733-9733/cn.codingblock.view I/——Layout: onTouchEvent: 2 | 是否消耗事件:true
01-05 19:03:21.877 9733-9733/cn.codingblock.view I/Activity: dispatchTouchEvent: 1 | 分发事件
01-05 19:03:21.877 9733-9733/cn.codingblock.view I/——Layout: dispatchTouchEvent: 1 | 分发事件
01-05 19:03:21.877 9733-9733/cn.codingblock.view I/——Layout: onTouchEvent: 1 | 是否消耗事件:true

事件分发机制是Android中非凡关键的贰个知识点,相同的时间也是难点,相信到目前截至非常多Android开辟者对事件分发机制并从未贰个可怜系统的认知,当然也包括博主个人在内。只怕在平常的支出职业中大家并从未察觉到事件分发机制起到的效果,其实它是时刻存在的只是大家不领悟而已,如同有的滑行冲突、点击事件之间的争辨等等非常多是因为事件分发管理不当导致的。想起了博主高校时做过二个小品种,里面就应时而生了滑动争持的难题,即使最终在英特网一步步望着外人的教程也糊里糊涂的消除了,但究竟不知其所以然,那么后天就让大家一起来深远的研讨一下风浪分发机制吗。