Android View框架总结(七)View事件分发机制

请尊重分享成果,转载请注明出处:
http://blog.csdn.net/hejjunlin/article/details/52282833

View布局告一段落,从本篇开始View事件相关分析,今天分析的是View的事件分发机制(PS:本篇文章中源码均是android 6.0,请知晓

  • View 事件的分发机制
  • dispatchTouchEvent
  • onTouchEvent
  • 案例

事件通常重要的有如下三种:
MotionEvent.ACTION_DOWN 按下View,是所有事件的开始
MotionEvent.ACTION_MOVE 滑动事件
MotionEvent.ACTION_UP 与down对应,表示抬起
事件的响应原理:
在android系统中,最广泛应用的就是监听、回调,进而形成了事件响应的过程。通俗就是说,你出去度假,提前预定过某酒店并注册,你在去那儿时,就能办入往手续,不用重新注册。立刻享用你的房间就行。
首先,我们要熟悉dispatchTouchEvent和onTouchEvent两个方法,话不多说,read the fucking source

View.java -> dispatchTouchEvent()

Android View框架总结(七)View事件分发机制_第1张图片
Android View框架总结(七)View事件分发机制_第2张图片

View.java -> onTouchEvent()

Android View框架总结(七)View事件分发机制_第3张图片
Android View框架总结(七)View事件分发机制_第4张图片
Android View框架总结(七)View事件分发机制_第5张图片
Android View框架总结(七)View事件分发机制_第6张图片
Android View框架总结(七)View事件分发机制_第7张图片

以上代码补充点:一个clickable或者longclickable的View是一直要消费Touch事件的,而一般的View既不是clickable也不是longclickable的(即不会消费Touch事件,只会执行ACTION_DOWN而不会执行ACTION_MOVE和ACTION_UP) Button是clickable的,可以消费Touch事件,但是我们可以通过setClickable()和setLongClickable()来设置View是否为clickable和longClickable。当然还可以通过重写View的onTouchEvent()方法来控制Touch事件的消费与否

View.java -> CheckForTap()

Android View框架总结(七)View事件分发机制_第8张图片

View.java -> checkForLongClick()

Android View框架总结(七)View事件分发机制_第9张图片

View.java.$CheckForLongPress -> run()

Android View框架总结(七)View事件分发机制_第10张图片

View.java.$CheckForLongPress -> performClick()

Android View框架总结(七)View事件分发机制_第11张图片

Android View框架总结(七)View事件分发机制_第12张图片

看个小例子,我们知道通常来说,Button、ImageView、TextView等控件都是继承父类View来实现的。RelativeLayout、LinearLayout、FrameLayout等布局都是继承父类ViewGroup来实现的,下面选 Button来演示View事件分发,当然我也会切换TextView,来看看它们是否有不同之处:
MainActivity,给EventButton设置了OnTouchListener监听,同时它本身有onTouchEvent,及onDispatchTouchEvent

Android View框架总结(七)View事件分发机制_第13张图片
Android View框架总结(七)View事件分发机制_第14张图片

这是一个自定义的button

Android View框架总结(七)View事件分发机制_第15张图片
Android View框架总结(七)View事件分发机制_第16张图片

布局文件

Android View框架总结(七)View事件分发机制_第17张图片

运行在studio,在手机上如图:

Android View框架总结(七)View事件分发机制_第18张图片

点击按钮,看日志输出:

Android View框架总结(七)View事件分发机制_第19张图片

可以看到,执行过程为
dispatchTouchEvent() -> setOnTouchListener() -> onTouchEvent()

如果手指一直长按,超过系统认为的时间,那么就认为是一次长按键,可以发现是在down时触发的,这和我们分析源代码时,是对应起来的,当UP时,触发onClick
在这说下,如果上面的EventButton继承TextView的话,按下抬起,会有一个特别现象,我可以告诉大家现象:就是只有dispatchTouchEvent ACTION_DOWN,onTouch ACTION_DOWN,onTouchEvent ACTION_DOWN这三个,你移动,或者抬起,是没有MOVE,或者UP的,这个答案,我下篇开头告诉大家(细心同学在本篇中也可找到答案,嘿嘿)。

Android View框架总结(七)View事件分发机制_第20张图片

从以上log可看出,设置了onLongClickListener是先执行的,那么要想执行点击事件,这个View就必须要消费ACTION_DOWN和ACTION_MOVE事件,并且没有设置OnLongClickListener的情况下,如果设置了OnLongClickListener的情况下,需要onLongClick()返回false才能执行到onClick()方法,也许你又会纳闷,一般的View默认是不消费touch事件的,这不是和你上面说的相违背嘛,我们要向执行click事件必须要调用setOnClickListener()来设置OnClickListener接口,看下这个callback:

Android View框架总结(七)View事件分发机制_第21张图片

也就是说,这个view如果不是/clickable的,在设转置setOnClickListener时,会设置一个clickable为true.

以下过程来用一张图来结尾:

Android View框架总结(七)View事件分发机制_第22张图片

至此,先分析到这里,确实有点晚了。~@~

第一时间获得博客更新提醒,以及更多android干货,源码分析,欢迎关注我的微信公众号,扫一扫下方二维码或者长按识别二维码,即可关注。

这里写图片描述

如果你觉得好,随手点赞,也是对笔者的肯定,也可以分享此公众号给你更多的人,原创不易

你可能感兴趣的:(Android,View框架(基于6.0源码))