Android事件的分发机制
来源:互联网 发布:薛之谦男装店淘宝地址 编辑:程序博客网 时间:2024/05/19 13:28
PhoneWindow的结构
Activity有一个PhoneWindow类型的成员变量mWindow,PhoneWindow是每一个Activity的主窗口类,PhoneWindow里面有一个DecorView类型的成员变量mDecor。
DecorView继承自FrameLayout,我们通过setContentView所设置进去的内容是在id为content的ViewGroup下的,这个ViewGroup和DecorView之间有一些额外的布局,比如ActionBar等,不同的UI风格,额外的布局是不一样的
容易混淆的方法名字
在看源码的过程中,如果没有弄清楚xxxTouchEvent方法的作用是什么、它是哪个类的方法、他是父类的方法还是被重载的方法,那么就很容易弄得云里雾里,找不清楚方向,我把涉及的主要方法画在了上面两个图中。
dispatchTouchEvent: ViewGroup的此方法作用是向它的子View分发事件,View的此方法作用是处理onTouch和onTouchEvent的调用
onInterceptTouchEvent:此方法是ViewGroup的方法,在此方法中可以拦截要传递给子View的事件
onTouch:是OnTouchListener的方法,调用时机先于onTouchEvent,如果在此方法中返回了true,那么onTouchEvent就收不到事件
onTouchEvent:是View的方法,在此方法中处理具体的DOWN、UP、MOVE事件,判断是否形成了click、long click等,如果判断到形成了click事件,那么就会调用OnClickListener的onClick方法
最精简的伪代码描述事件分发算法
android事件分发的代码很多而且庞杂,我把它用最精简的伪代码描述如下,当然这只代表最主干的情况,代表的是普通的一根手指按下又弹起的情况的描述
我们可以看到这是一个递归算法,理解的要点
第13行,这里的child有两种情况,如果是ViewGroup,那么就是对dispatchTouchEvent的递归调用,它的返回值代表了它所代表的子树是否要处理这个事件;如果View,它调用dispatchTouchEvent的作用就是处理onTouch和onTouchEvent的调用顺序
第20行,如果判断到要截获事件,那么这个事件就直接给了当前ViewGroup的父类的dispatchTouchEvent方法,而ViewGroup的父类是谁?就是View,所以这里调用的dispatchTouchEvent就是去真正地在叶子节点处理touch事件了
第24行,代表的是自己不截获且所有子View都不处理的情况,这个时候就交给自己处理,如果自己还不处理?handled就会为false,继续给上一级父亲处理
子View是如何判断是否要处理事件的?
protected boolean isTransformedTouchPointInView(float x, float y, View child, PointF outLocalPoint) { final float[] point = getTempPoint(); point[0] = x; point[1] = y; transformPointToViewLocal(point, child); final boolean isInView = child.pointInView(point[0], point[1]); if (isInView && outLocalPoint != null) { outLocalPoint.set(point[0], point[1]); } return isInView;}public void transformPointToViewLocal(float[] point, View child) { point[0] += mScrollX - child.mLeft; point[1] += mScrollY - child.mTop; if (!child.hasIdentityMatrix()) { child.getInverseMatrix().mapPoints(point); }}final boolean pointInView(float localX, float localY) { return localX >= 0 && localX < (mRight - mLeft) && localY >= 0 && localY < (mBottom - mTop);}
我们可以看到所谓的transformTouchEvent就是把绝对坐标转换到view的相对坐标,怎么判断view要不要处理事件?判断相对坐标是不是在子view的范围内
- Android的事件分发机制
- Android事件的分发机制
- Android的事件分发机制
- Android 的事件分发机制
- android 事件的分发机制
- Android 的事件分发机制
- Android事件的分发机制
- Android的事件分发机制
- android事件的分发机制
- Android的事件分发机制
- android的事件分发机制
- Android的事件分发机制
- Android的事件分发机制
- Android的事件分发机制
- Android事件的分发机制
- Android 的事件分发机制
- Android 事件的分发机制
- Android 事件的分发机制
- findViewById(R.id.xxx)返回Null
- 设计模式之代理模式
- Padre使用
- 有道翻译API+Jackson+HttpClient
- 微信公众号运营手册
- Android事件的分发机制
- linux 重定向 1>&2 2>&1的各种变形理解
- 【C/C++】:如何获得一个float数的小数位数?
- 使用Linux安装软件时遇到的一系列问题
- SPI协议
- Java并发包Concurrent下Callable和Future实战
- 如何找出数组中重复次数最多的数
- python 模拟126邮箱发送邮件
- 认清MVC,MVP和MVVM