大话Android事件分发机制

作者: ldlywt | 来源:发表于2017-05-07 22:49 被阅读96次

1 前言

最近在找工作,面试官经常会问有没有做个自定义view,接下来的话一般都会问Android事件分发机制。看过很多次,但是每隔一段时间又忘记了,或者面试时说的也很乱。我想了下,用讲故事的方式来说这个感觉不错,小白都能看懂。

2 事件分发机制分类

  • 事件的分发

public boolean dispatchTouchEvent(MotionEvent ev)
此方法虽然是事件分发的第一步,但一般情况下,我们不太会去改写这个方法,所以暂时不管这个方法。

  • 事件的拦截(View中没有该方法)

public boolean onInterceptTouchEvent(MotionEvent event)
返回值理解:true,拦截,不继续;false,不拦截,继续流程。
默认值是false。

  • 事件的处理

public boolean onTouchEvent(MotionEvent event)
返回值理解:true,处理了,不用审核了;false,给上级处理。
默认值是false。

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
    return super.onTouchEvent(event);
}

3 开始讲故事

假如你是一家小公司的程序猿,你们公司是给第三方客户做App的,其实就是一家外包公司。
公司主要有三个角色:身为程序猿的你,你的经理,公司的老板。
分别取名为: MyView、MyManagerViewGroup、MyBossViewGroup
对应如下图:


Android事件分发机制.png

3.1 事件的拦截

与事件拦截机制有关的方法是:

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return super.onInterceptTouchEvent(ev);
    }
3.1.1 全部未拦截

有一天,客户下了个订单,订单提交给boss。boss说可以做(返回false,不拦截),然后下发给经理,经理也说可以做(返回false,不拦截),经理再下发给你,因为你是程序猿没人权,不能做也得做,所以没有拦截判断。
这也是未重写任何方法,未修改任何代码的情况下,默认返回是false。
此时顺序是:

老板-->经理-->你

类似于当你点击蓝色的view颜色块时,事件的传递顺序是:

红-->绿-->蓝
MyBossViewGroup-->MyManagerViewGroup-->MyView

logcat打印如下:


全部未拦截.png

借用Android群英传图:


事件处理过程
3.1.2 在中间拦截

客户下的订单在boss那里通过了(返回false,不拦截)。但是到了经理那里,经理觉得这App太难做了,公司实力不够做不了(返回true,拦截,不继续)。
事件在经理处就消费掉了,你挺开心的,因为跟你没什么关系,可以不要加班了。

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.d(TAG, "MyManagerViewGroup onInterceptTouchEvent--> " + ev.getAction());
//        return super.onInterceptTouchEvent(ev);
        return true;
    }

此时顺序是:

老板-->经理

事件的传递顺序是:

红-->绿
MyBossViewGroup-->MyManagerViewGroup

在中间拦截.png

借用Android群英传图:

在中间拦截.png
3.1.3 在最上层拦截

客户下了个小单后,boss觉得利润太低了,不是很想做(返回true,拦截,不继续),显然没你跟经理什么事。
事件在boss处就消费掉了,你和经理都挺开心的,因为跟你们没什么关系,可以开开心心回家了。
此时顺序是:

老板

事件的传递顺序是:


MyBossViewGroup

在最上层拦截.png

借用Android群英传图:

在最上层拦截.png

3.2 事件的处理

与事件处理机制有关的方法是

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return super.onTouchEvent(event);
    }
3.2.1 正常处理

任务下发后,你发现客户的App挺容易做的,于是你很快就做完了。做完后交给经理看,经理看完感觉还不错,再交给boss审核。
这也是未重写任何方法,未修改任何代码的情况下。
此时顺序是:

你做完任务-->经理审核-->boss审核

事件的传递顺序是:

蓝-->绿-->红
View onTouchEvent-->MyManagerViewGroup onTouchEvent-->MyBossViewGroup onTouchEvent

正常处理.png
3.2.2 在View处理

任务下发后,你发现客户的App太难做了,估计要疯狂加班很长时间,想到很久每周末,你的小宇宙爆发了,老子不干了!(返回true,处理了)

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.v(TAG, "View onTouchEvent " + event.getAction());
//        return super.onTouchEvent(event);
        return true;
    }

此时顺序是:

你辞职不管

事件的传递顺序是:


View onTouchEvent

在View处理.png

这里的log打印长了很多,还有0和1两种情况。
当点击屏幕通常会产生两或三个事件——按下(MotionEvent.ACTION_DOWN),滑动(MotionEvent.ACTION_MOVE),抬起手(MotionEvent.ACTION_UP)。

0表示ACTION_DOWN事件
1表示ACTION_UP事件
2表示ACTION_MOVE事件

在看面的Log日志,发现在执行ACTION_DOWN事件时,MyView的onTouchEvent方法返回true后,两个ViewGroup都不执行onTouchEvent方法,这也就是说MyView直接结束了这次事件,不再传回两个ViewGroup。但是,在结束了ACTION_DOWN事件后,紧接着开始执行了ACTION_UP事件,说明只有当MyView的onTouchEvent返回true才会执行下面的事件。

3.2.3 在中间处理

boss布置完任务后发现太忙了,对经理说:这个App的效果交给你来全权处理,不要向我汇报了。
此时顺序是:

你做完任务-->经理审核

事件的传递顺序是:

蓝-->绿
View onTouchEvent-->MyManagerViewGroup onTouchEvent

在中间处理.png

返回true后直接结束事件,但是在第二次处理事件的时候,MyView就没再参与事件的处理,也就是说一旦onTouchEvent返回值为true就会导致在本次处理过程中后面的事件将不再分发给该View。

相关文章

网友评论

  • d16b48817da9:现在安卓在北京15k以上的好难找啊
    d16b48817da9:@假装是程序猿丶 安卓不好找 人太多了 后台前端好点
    ldlywt:感觉今年深圳3年左右工作经验,15k不是很难找。。。北京行情这么差?

本文标题:大话Android事件分发机制

本文链接:https://www.haomeiwen.com/subject/ujlptxtx.html