设计师该怎么投资投机

事件分发机制是Android中好重大的一个知识点,同时也是难题,相信到目前为止很多Android开发者对事件分发机制并无一个大系统的认识,当然也席卷博主个人在内。可能在平时的支付工作吃我们并没有发现及事件分发机制于及之意图,其实她是随时在的只是我们无明白而已,就比如有滑动冲突、点击事件之间的撞等等大多是坐事件分发处理不当导致的。想起了博主大学时举行了一个稍微品种,里面纵使起了滑动冲突之问题,虽然最终在网上一步步禁闭正在别人的课程也糊里糊涂的化解了,但终究不知其所以然,那么今天就算为我们一道来深切之追一下事变分发机制吧。

深信我们都闻讯了“投资投机才是极端好的投资”这样的意。阁主对先辈们这么的率真教育一向秉持着未反对无支持之态势,同样句子话或一个看法要在相应的语境中错过领略才会体会到它的意境。毕竟不是对方,没经验了对方所涉之事情,所以不能回答,也未能判断,不过看得几近矣,听得多了,只是觉得假如大家还如此说之口舌,会错过思就件事,但必须依据自己之莫过于状况要进展认知和利用,生搬硬套大多数情景下会出问题。

嗬是事件分发机制?

说了半天的事件分发机制那到底是只底东西也?我们不用管其想象的那强深莫测,不要在思想及吃好要上阻碍,其实挺易理解,博主的领悟是:简单的话,事件分发机制就算是Android系统对事件传递过程规定的一致栽事件传递规则,事件都见面依照这个规则进行分发传递。

每当研讨事件分发机制之前,我们先来确定一下剖析的步调,化整为零,各个击破:

  • 干明白分析目标:MotionEvent。
  • 打听三单章程:dispatchTouchEvent(MotionEvent
    event)、onInterceptTouchEvent(Motion
    event)、onTouchEvent(MotionEvent event)。
  • MotionEvent事件的传递过程
  • 小结

干活立几年,说说好对这个意见的感受。阁主比较有赞成的见解,问题的主要不是跟不容许这理念,问题的关键在于同意是视角之后该怎样做,也即是何等投资投机。

MotionEvent

骨子里点击事件之分发过程就是对准MotionEvent事件的散发过程,当用户点击操作以下后,MotionEvent事件随后发出并经自然的条条框框传递及指定的View上,这个传递的长河和规则就是是事件分发机制。

若果点击操作触发MotionEvent事件是一个风波流或说是一个波序列,其一流的风波类有如下三种植:

  • MotionEvent.ACTION_DOWN:手指刚点下屏幕时接触此类型。
  • MotionEvent.ACTION_MOVE:手指在屏幕及动时见面频繁接触此类型。
  • MotionEvent.ACTION_UP:手指在屏幕及抬起时接触此类型。

假使特别注意的是,通常状态下一个MotionEvent事件序列包含一个 ACTION_DOWN
若干个 ACTION_MOVE 和 ACTION_UP
是一个完完全全的事件序列。(点下来就抬起指头时,会只有生 ACTION_DOWN 和
ACTION_UP,这吗是一个完好的轩然大波序列)

近些年阁主更温和稍慢,一凡为好发生新的靶子,时间跟生机正处在调整的状态被,以前每周2~3糟创新,变成现在之平等健全一样还。内容呢由前期的教大家怎样设计文本,到开源项目于大家算的sketch源文件,到现行底错过开展双重怪层次的职业和人生目标的思考。一方面是祥和于不停成长,二是体会到那么句话,“授人以鱼勿使授人以渔”,技术层次的物最好教,网上也从都非亏,而真正考虑方面的变型才是一个人境遇上变化的启,网上也很少会找到职场人观念不断转变之实在记录,于是为是当前阁主能也大伙做的尽有价的从事。

dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent

  • boolean dispatchTouchEvent (MotionEvent event):

分发事件,只要事件会传递至即View就自然会调用此方式,其归来回值是一个布尔类型表示是否消耗事件。返回true代表吃事件,事件流的继续有还会跟着传递过来;返回false代表不吃事件,事件流的延续有即不再传递给斯。

  • boolean onInterceptTouchEvent (MotionEvent ev):

本条方表示是否拦截MotionEvent事件,只有ViewGroup类型的控件才发生这个措施。如果这个措施返回true表示拦截事件,事件将传递给当下View的onTouchEvent()方法,而不再为该属下的View传递。如果是方返回false表示不阻碍事件,事件将传递给下属View的dispatchTouchEvent()。

  • boolean onTouchEvent (MotionEvent event):

此方用来拍卖MotionEvent,返回值表示是否消耗事件。返回true表示耗事件,那么事件流的连续有还会传送过来;返回false表示不吃事件,事件将交给上级View的onTouchEvent()处理,如果上级View的onTouchEvent()仍然返回false,那么事件将再付诸上级的上面处理,以此类推,如果各级View的onTouchEvent()都未吃事件,那么事件结尾以提交Activity的onTouchEvent()处理。

上文说了这样多还是未足够具体,先用流程图大体说明一个以上三独主意的关联,及调用流程,下文还会组成具体示例详细说明以事件分发传递着逐一艺术的调用规则。

三者关系约如下图:

图片 1

设计师该怎么投资投机呢?依照阁主的观念,分为日精力以及金点滴万分者。

MotionEvent事件传递过程

当手指点击屏幕有一个Touch事件后,事件仍Activity->Window->View的相继依次传递。

第一会见传递让Activity的dispatchTouchEvent(),在这方法中会用出于Window处理,接着事件会传递给根View,根View接收到事件后即会见以事件分发机制去处理事件。

根View在这边就是一个ViewGroup,它当承受到事件后会见调用dispatchTouchEvent(),在是方式中会通过onInterceptTouchEvent()方法判断是否拦截事件,如果onInterceptTouchEvent()返回true就象征它而拦事件,事件将传递给当下ViewGroup的onTouchEvent()。如果onInterceptTouchEvent()放回false就象征其不遮事件,事件将污染被那个属下的View,调用下级View的dispatchTouchEvent()。

根View的部下View可能又是一个ViewGroup,如果这样的话其传递流程与根View一样。无论根View的部属View是休是ViewGroup,如果未阻止事件,最终事件会传递至一个纯View的控件上。

当一个View(纯View控件)接收至事件后,也会调用其dispatchTouchEvent(),然后在这个办法中会调用当前View的onTouchEvent(),如果onTouchEvent()返回true则象征要处理是事件。如果回到false表示不吃事件,其上司View的onTouchEvent()将受调用,则事件流的持续有不再传递至眼前View,在一个风波流中也不见面还调用当前View的dispatchTouchEvent()。

连通下去通过切实示例来查事件传递的流程:

时光跟活力的投入

示例一,默认情况下的波传递流程

创立3单近乎,一个Activity、一个继往开来自LinearLayout的View,一个持续自Button的View,并重新写他们之dispatchTouchEvent()、onIntercepteTouchEvent()、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的onTouchEvent方法中,此时onTouchEvent方法返回true,表示要处理事件,所以事件流的继承有还通过log中的流水线到达了View的onTouchEvent方法中。

咱们的年华一般消费在当时几乎独面,工作、家庭、社交、娱乐爱好这几乎单方面。有只观点首先需澄清的是,费了时光纵得花精力这样效率才见面强。比方说以上班,但一样天即这样混过去不曾花费精力,其实效率极低,时间之利用率没有上来,所以阁主的见地就是岁月精力是环环相扣的,不可分割。再来探哪分配时。

示例二、在示例一的底蕴及,让View的onTouchEvent不吃事件时之传递流程

连接下去为方的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的onTouchEvent方法处理,而从log可以观看ViewGroup的onTouchEvent默认为未吃事件,所以事件由提交Activity的onTouchEvent方法处理,最终事件流的持续有不再传递让ViewGroup和View,而是径直传送给Activity的onTouchEvent处理。

欠拒绝就不肯,找对团结无比重大的事体,别追求什么还开好,也变更追求做老好人讨别人欢心,哪怕这个人口是您领导。领导满意的莫过于呢是若最关键之做事力量,工作力量上了,其它的组成部分小节领导反而会谅解,工作力量很其它都是对牛弹琴。家庭,阁主经验有限只说说十分的尺码,遵从自己之胸,平衡好状态后择自己不过畅快的状态,自己非开心受伤害的双重多。

示例三、在示例二的功底及给ViewGroup消耗事件

修改EventDispatchLinearLayout的onTouchEvent(),让那归来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的onTouchEvent中,发现其而吃事件,事件流的延续有就是非以传递让View,也未以调用ViewGroup的onInterceptTouchEvent方法,因为都知晓View不处理事件,所以无必要更经onInterceptTouchEvent方法来判断了。

社交,一般企业周末同事等见面约在一头吃个饭,活动活动哟的。阁主以前为常去,最近发觉,去的食指大半大家之肥力分散,反而没有于至交流沟通的目的,去的人掉,气氛呢绝非养起来有些发尴尬,所以后来阁主发现,除非走团队的凡好之趣味所当才为在趣味而错过,而非见面为团圆如果聚会。别担心别人见面说公切莫合群什么的,其实大家都异常忙碌没过多之活力放在你身上,哪怕是说一样词“来吧”,可能啊就算是客气一下,自己也无多思量,放心,缺了谁大家还见面游戏得甚开心。娱乐爱好是好学会放松的岁月,无论喜欢什么,打游戏、下伙房、插花等等,都见面为祥和之心灵有所缓和,值得自己花工夫在地方~

示例四、如果以ViewGroup的onInterceptTouchEvent中归了true拦截了风波,整个事件将不再传递给View而是直接到由ViewGroup的onTouchEvent处理。

修改EventDispatchLinearLayout的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

光阴及究竟的法的凡,拿时间花在针对自己方便之事情上,其他的且不到底事儿~

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

当EventDispatchActivity的onCreate()方法中添加如下代码,并以EventDispatchLinearLayout和EventDispatchTestView的各个艺术的归来值都还原成示例一吃的状态。

@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的onTouchEvent()方法执行的。如果当onTouch()消耗了风波(返回true),那么事件将无在传递给onTouchEvent()方法,最终为不见面调用onClick()方法。
  • 为View绑定的OnClickListener中的onClick()方法优先级最低,是于漫天事件流了晚才见面让调用,也不怕是索要经手指的准下–抬起这个过程才见面触发onClick()方法。

钱的投入

小结

为更好之知,可以把事件流看成是同样帮人,把ACTION_DOWN类型看做探路人,探路人按规定的线先倒相同方方面面,直到走及View的onTouchEvent这里,如果onTouchEvent返回true,可理解成这路通,后续部队可以回复。如果回去false,可以领略成这个路不通,然后探路人再至Layout(ViewGroup)的onTouchEvent中问路连通不属,如果接的口舌后续部队虽甭还夺View那里了,直接到ViewGroup这来就可了。而如果ViewGroup这里路呢打断,那么探路人就不得不去Activity的onTouchEvent那里了,后续部队为直接去Activity的onTouchEvent这里就是好了。


末尾想说之是,本系列文章也博主对Android知识进行再梳理,查缺补漏之学过程,一方面是对协调忘记的东西加以复习重新掌握,另一方面相信于重新学习的经过中势必会起英雄的初抱,如果您吗来和自己平的想法,不妨关注自己同学习,互相探讨,共同进步!

参考文献:

  • 《Android开发方式探索》

阁主不尚百分百底节约和百分百的花费,有个度就推行。比方说一个月份至手10000片的语,一半是使存的,还生5000,可能房租会为此少1000~3000+不顶的档次,然后剩下的是各种开销。阁主明白在帝都这样的均等丝都,一个月份费用包含房租在内5000第一是蛮忐忑之。在马上不安之情景下,阁主建议大家分出几只有,一凡买进书投资投机的大脑,什么样的书阁主之前也勾勒了类似书目的推荐,有业内的也罢发出正规外之。二是指向自己吓一点,在投机在意的业务上扭转太抠,这样被投机苦哈哈的,会影响幸福感,整个人之风水都无针对。女生吃好购买点好之护肤品,男生买点健身装备,都是很好之投资。如果钱未敷用,说明自己挣能力还无和上去,也不要动储蓄中的5000,而是想方法去赚钱外快,至少在生城市工作如果稍微动点脑筋付出点体力,外快是好的。

还有少数阁主比较提倡的凡,住在距离柜即一点底地方,而挑选公司的时光吗尽量选偏市中心的地方。在市中心工作大多人成长率会愈多,信息太集中,也是日最高效之运用。住在局附近,健身也无须纠结在家附近要于公司附近做,住远了心一直会想着啊时搬得近乎一点,又是一模一样种植精力的荒废。

设计师会破产装备,Mac、iPhone等等都是同样笔画非小之费,但当局主要说的凡,这些开支都是值得的,买了足为此一些年,好的家伙会增长自己之工作效率,省下不清楚有些而所发现不顶之流年。如果当不打便分期付款,现在每大信用卡都倡导这样的从业,通货膨胀为钱莫贵反而这样大质量的物件更值钱。

以上是阁主这几乎年的职场感悟,比较适用于正工作之伴儿,每个人情况尚且不顶雷同,所以大家都得以因自己的作业情况只要展开调整,没有科学的答案,只要自己每日睡前中心备感充实,整个人是进步移动的状态就吓之状态~
留言区欢迎大家讨论~