Android事件转发机制—源码分析(一)
来源:互联网 发布:linux 解压gz文件脚本 编辑:程序博客网 时间:2024/06/04 19:14
这是小王君熬夜写的博客,虽然很晚,还是坚持写下去吧!(注:本文是以ViewGroup的点击事件的处理为例来分析)
一,在分析源码前,我们先总结下事件转发机制的一些简单结论:
1,当用户开始触摸activity时,Activity调用diaptcherTouchEvent开始转发,会一层层的向下进行转发,也就是每个View都会调用diaptcherTouchEvent方法。这里需要注意的是,ViewGroup在将事件转发给子view的时候,根据子view添加进ViewGroup时间的逆序排列转发事件,这是android框架的内部机制实现的。
2,当事件分发到最后一个子View的时,会以从下往上的顺序调用onTouchEvent方法。如果哪个view对这个事件感兴趣,就处理该事件,执行onTouchEvent里面的代码,如果感兴趣了还返回true,那么事件就被消费了,被吃了就木有啦,上层view的onTouchEvent就不会再接收事件了;否则一直将事件传递给上层的view的onTouchEvent,直到最后Activity的onTouchEvent收场处理。
3,在结论1中,如果在事件转发的中间,某一个view对事件感兴趣中途进行拦截,会调用该view的onInterceptTouchEvent方法,若该方法返回true,就会调用该view的onTouchEvent方法对事件进行处理,就不会再往下转发事件了,否则会一直转发下去。
这里,我们画一个流程图给大家看,如下:
Activity(diaptcherTouchEvent)→ViewGroup(diaptcherTouchEvent) →........→ 子View(diaptcherTouchEvent)
↓ 拦截,onInterceptTouchEvent
Activity(onTouchEvent) ← ViewGroup(onTouchEvent) ←........← 子View(onTouchEvent)
源码分析入口,首先进入Activity类查阅如下:
Activity.class中:
分析:事件触摸是封装在MotionEvent中进行传递;
Activity转发的时候,先交给Activity所附属的Window,于是调用PhoneWindow的superDispatchTouchEvent()方法。
接下来,我们进入PhoneWindow类里进行查阅如下:
注:类PhoneWindow继承了Window ,Window只有这一个子类; PhoneWindow.class在framework源码中。
分析:mDecor 就是DecorView,PhoneWindow将事件传递交给DecorView处理。
接下来,我们进入DecorView类进行查阅如下:
DecorView如何将事件转发到xml中布局的根view,这里不作分析,反正肯定是可以转发过来的,因为我们写的xml布局是能接受触摸事件的。这里的根view,就是setContentView中最外层的view,一般都是一个组控件ViewGroup。
分析:DecorView将事件处理交给了super爸爸,这个爸爸就是FrameLayout,爸爸继承爷爷ViewGroup,实际就是ViewGroup的dispatchTouchEvent()。至于接下来,我们要开始查阅ViewGroup的源码,如下:
这里主要看注释的核心代码,能梳理清楚事件转发的流程即可,不必理解每一行代码
分析:super.dispatchTouchEvent(event)调用爸爸的方法
接下来,我们继续查阅View.class
分析:
li != null && li.mOnTouchListener != null为防止空指针,代码健壮性更强;
主要看后面两个:
一 ,(mViewFlags & ENABLED_MASK) == ENABLED 为true时指控件可clickable。
二 ,li.mOnTouchListener.onTouch(this, event) 回调接口的方法(由用户调用view.setOnTouchListener(..)实例化监听器接口);
当onTouch(..)返回true(四个条件都为true时),在方法onTouch(..)中处理点击事件。
当onTouch返回false时(或者四个条件任一为false),执行该View自己的onTouchEvent(event)处理该点击事件。
当onTouch返回false时(或者四个条件任一为false),执行该View自己的onTouchEvent(event)处理该点击事件。
如果事件处理了,不用给Activity的onTouchEvent()收场处理,否则由Activity的onTouchEvent()收场处理事件。
总结一下转发流程经过的窗口和view:
Acticity——>PhoneWindow——>DecorView——>—>根view—>..........—>最后一个子view
注:根view,也就是setContentView(R.layout.XX)中的布局
下图是用Eclipse的Hierarchy View查看某一页面的布局结构,其实每一个布局结构的根都是PhoneWindow$DecorView。
到这里,源码分析就结束了。我们想进步,还是需要读者自己去翻开源码查阅,才能更深刻理解事件分发机制。
辛苦大家能看到这里,文章有不够准确的地方,期待大家能在下面评论中指出,一起学习进步!!!
———小王君 (*^__^*)
阅读全文
0 0
- Android事件转发机制—源码分析(一)
- Android—— View事件分发机制的源码分析
- Android源码分析-点击事件派发机制
- Android源码分析-点击事件派发机制
- Android源码分析-点击事件派发机制
- Android源码分析-点击事件派发机制
- Android源码分析-点击事件派发机制
- Android源码分析-点击事件派发机制
- Android源码分析-点击事件派发机制
- Android源码分析-点击事件派发机制
- Android源码分析-点击事件派发机制
- Android事件处理机制轻量级源码分析
- Android事件传递机制 源码分析
- Android源码分析-点击事件派发机制
- Android源码分析-点击事件派发机制
- Android事件分发机制源码分析
- Android View事件传递机制-源码分析
- Android View事件传递机制-源码分析
- 文件上传
- codeforces 556D Case of Fugitive
- 安卓+七牛云的第三方图片存储实践
- 将Linux文件清空的几种方法
- 欢迎使用CSDN-markdown编辑器
- Android事件转发机制—源码分析(一)
- 汉罗塔问题(修改版)---递归和栈实现
- 《聊聊架构》第一部分读书笔记
- Android动态加载ClassLoader
- Dialog(二)------列表Dialog
- mycat 之datanode datahost writehost readhost 区别
- method ID not in [0, 0xffff]: 65536” error解决办法
- 定时执行某段程序
- 前端效果——持续更新。。。