解析Android点击事件分发机制

解析Android点击事件分发机制,第1张

概述开头说说初衷网上关于点击事件分发的文章一搜一大堆,标题一看,不是“30分钟让你弄明白XXX”就是“这是讲解XXX最好的文章”,满怀憧憬与信心,忍不住兴奋的点进去一看,发现不是代码就全是图,我基本上看完了所有相

开头说说初衷

网上关于点击事件分发的文章一搜一大堆,标题一看,不是“30分钟让你弄明白XXX”就是“这是讲解XXX最好的文章”,满怀憧憬与信心,忍不住兴奋的点进去一看,发现不是代码就全是图,我基本上看完了所有相关的文章,结果硬是看了三个小时也没搞懂。所以最后还是决定自己去试一试,看一看点击事件分发到底是怎么个流程,我写的肯定不会比其他文章好多少,但是呢,带着一个初学者的心,去分析这个东西,自己能弄明白的同时,也让想学习这个的人看了之后有些许收获,那就足够了。

运行的环境

所有的源码都基于API 26,也就是Android8.0奥利奥,AndroID Studio 3.0.1,想要自己敲代码试试的同学可以参考一下

进入正题

分析点击事件分发流程,是想弄明白当我们用手指去点击屏幕的时候,分为三个动作,按下,移动和抬起,屏幕上的东西是怎么知道我们点了它的,在这中间到底经历了什么。所以要先来模拟一下这个点击的过程,看看到底调用了哪些方法。

搭建最简单的结构

新建Activity,重写dispatchtouchEvent和ontouchEvent,前面的方法负责点击事件的分发,后面的方法负责点击事件的消耗,然后打印三种触摸事件的触发

private static final String TAG = MainActivity.class.getSimplename();@OverrIDe  public boolean ontouchEvent(MotionEvent event) {    int action = event.getAction();    switch (action) {      case MotionEvent.ACTION_DOWN:        Log.d(TAG,"Activity ontouchEvent ACTION_DOWN");//按下        break;      case MotionEvent.ACTION_MOVE:        Log.d(TAG,"Activity ontouchEvent ACTION_MOVE");//移动        break;      case MotionEvent.ACTION_UP:        Log.d(TAG,"Activity ontouchEvent ACTION_UP");//抬起        break;    }    return super.ontouchEvent(event);  }@OverrIDe  public boolean dispatchtouchEvent(MotionEvent ev) {    int action = ev.getAction();    switch (action) {      case MotionEvent.ACTION_DOWN:        Log.d(TAG,"Activity dispatchtouchEvent ACTION_DOWN");        break;      case MotionEvent.ACTION_MOVE:        Log.d(TAG,"Activity dispatchtouchEvent ACTION_MOVE");        break;      case MotionEvent.ACTION_UP:        Log.d(TAG,"Activity dispatchtouchEvent ACTION_UP");        break;    }    return super.dispatchtouchEvent(ev);  }  

新建一个类继承自linearLayout,同样也重写dispatchtouchEvent和ontouchEvent,还有因为linearLayout继承自VIEwGroup,VIEwGroup是可以拦截点击事件的,这个很好理解,因为控件都是放在他里面的嘛。所以还要重写onIntercepttouchEvent方法

@OverrIDe  public boolean onIntercepttouchEvent(MotionEvent ev) {    int action = ev.getAction();    switch (action) {      case MotionEvent.ACTION_DOWN:        Log.d(TAG,"onIntercepttouchEvent ACTION_DOWN");        break;      case MotionEvent.ACTION_MOVE:        Log.d(TAG,"onIntercepttouchEvent ACTION_MOVE");        break;      case MotionEvent.ACTION_UP:        Log.d(TAG,"onIntercepttouchEvent ACTION_UP");        break;      default:        break;    }    return false;  }

(这里有个重点).

这里有个需要注意的地方就是AndroID的控件有些是默认可以点击的(如button),还有一些是默认不可点击的(如TextVIEw)他们的分发是有一些不同的,这里我们先看不可点击的,新建一个类继承androID.support.v7.Widget.AppCompatTextVIEw,兼容的TextVIEw,同时跟Activity一样重写dispatchtouchEvent和ontouchEvent,代码不贴了,跟上面一样,它是普通控件,没有拦截的方法。

开始点击,移动手指后抬起

然后来点一点屏幕上的控件看看打印的log,dispatchtouchEvent和ontouchEvent都返回默认的实现super,onIntercepttouchEvent默认返回false,表示不拦截,默认的情况打印:

1.--------------------------------------D/MainActivity: Activity dispatchtouchEvent ACTION_DOWND/MyLayout: dispatchtouchEvent ACTION_DOWND/MyLayout: onIntercepttouchEvent ACTION_DOWND/MyTextVIEw: dispatchtouchEvent ACTION_DOWN2.--------------------------------------D/MyTextVIEw: ontouchEvent ACTION_DOWND/MyLayout: ontouchEvent ACTION_DOWND/MainActivity: Activity ontouchEvent ACTION_DOWN3.--------------------------------------D/MainActivity: Activity dispatchtouchEvent ACTION_MOVED/MainActivity: Activity ontouchEvent ACTION_MOVED/MainActivity: Activity dispatchtouchEvent ACTION_MOVED/MainActivity: Activity ontouchEvent ACTION_MOVED/MainActivity: Activity dispatchtouchEvent ACTION_UPD/MainActivity: Activity ontouchEvent ACTION_UP

这是默认的情况,把它分为三个阶段:

1. 事件的分发,从上到下,从Activity到Layout到Text的dispatchtouchEvent结束

2. 事件的消耗,从下到上,从Text到Layout到Activity的ontouchEvent结束

3. 这套动作的后续事件交给上个事件的最后消耗者,不经过其他控件的分发

三个函数的其他返回值

dispatchtouchEvent和ontouchEvent都有三种返回情况
- true
- false
- super.dispatchtouchEvent(ev)和super.ontouchEvent(event)

onIntercepttouchEvent有两种返回,true和false,这样来看, 组合起来真是情况太多了,写下来挨个分析看代码的话怕是要看晕,所以这里用一张图来看看所有的情况:

普通不可点击VIEw的事件分发流程

默认可点击控件的事件分发

比如button这种默认可以点击的控件,或者设置androID:clickable=”true”的控件,在分发流程中有一些不同,主要是ontouchEvent的默认方法不同,它直接消耗点击事件,不再往上传递。

可点击VIEw的事件分发流程

结语

事件的分发流程到此就结束了,目的已经达到了,找到了我们想要点击的那个按钮或者其他控件,总结下来就是从Activity经过VIEwGroup然后到VIEw依次分发,然后又从底向上确认自己是否消耗该事件,如果某个对象消耗了,动作的后续事件都由他来处理。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的解析Android点击事件分发机制全部内容,希望文章能够帮你解决解析Android点击事件分发机制所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1143321.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-31
下一篇2022-05-31

发表评论

登录后才能评论

评论列表(0条)

    保存