Android学习笔记之事件分发机制(二)
来源:互联网 发布:绘画 知乎 编辑:程序博客网 时间:2024/06/06 00:38
说明:关于安卓的事件分发机制总共有三篇,第一篇和第二篇我尝试着通过调试信息向大家说明一些情况,但相信我,越看你会觉得越乱.这跟事件分发机制的复杂有一定的关系.第一篇和第二篇其实只是在给最后一篇做铺垫而已,在最后一篇中我会借助源码和前面的铺垫尽可能的向你展示所有的细节.
前言
在 Android学习笔记之事件分发机制(一)中,由于写得有点急,没有认真对调试信息进行分析,后来在分析源码的过程中才发现自己写错了,现在已经修改好了.给大家造成了误导,在这里说声抱歉.
之前不想让篇幅太长,还有些东西没写完.在这篇博文中,继续上一篇的脚步,进一步对事件分发机制进行学习.
进一步
之前我们只是对一个按钮的触碰事件进行分析,但是你有没有想过这些事件是怎么传递到按钮上来的呢?所以今天要做的实验就是增加一个自定义Layout(嵌套着CustomButton)和重写Activity中相应的方法.
CustomLayout.java
public class CustomLayout extends LinearLayout { private static final String TAG = "event"; public CustomLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean dispatchTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.d(TAG, "CustomLayout---dispatchTouchEvent---action down"); break; case MotionEvent.ACTION_MOVE: Log.d(TAG, "CustomLayout---dispatchTouchEvent---action move"); break; case MotionEvent.ACTION_UP: Log.d(TAG, "CustomLayout---dispatchTouchEvent---action up"); break; } return super.dispatchTouchEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.d(TAG, "CustomLayout---onTouchEvent---action down"); break; case MotionEvent.ACTION_MOVE: Log.d(TAG, "CustomLayout---onTouchEvent---action move"); break; case MotionEvent.ACTION_UP: Log.d(TAG, "CustomLayout---onTouchEvent---action up"); break; } return super.onTouchEvent(event); }}
MainActivity.java
findViewById(R.id.layout).setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.d(TAG, "CustomLayout---onTouch---action down"); break; case MotionEvent.ACTION_MOVE: Log.d(TAG, "CustomLayout---onTouch---action move"); break; case MotionEvent.ACTION_UP: Log.d(TAG, "CustomLayout---onTouch---action up"); break; } return false; }}); @Overridepublic boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { 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);}@Overridepublic boolean dispatchTouchEvent(MotionEvent event) { switch (event.getAction()) { 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(event);}
注意:如果在onTouch
中返回true的话,是看不到后面onTouchEvent
的执行的.
点击一下按钮,可以看到:
dispatchTouchEvent
的执行顺序是这样的: Activity -> Layout -> View. 这样也很好理解,事件从Activity开始分发,然后从xml的最外层往最内层去传.
不知道大家有没有发现,我们写的有几个方法没有被执行到.
MainActivity: onTouchEvent
没有被执行到.
CustomLayout: onTouch
和onTouchEvent
都没有被执行到.
CustomButton: 所有方法都被执行到了.
先来分析这个CustomLayout.在第一篇中我说到了,View的各个方法执行顺序是这样的: dispatchTouchEvent
-> onTouch
-> onTouchEvent
-> onClick
.Layout本身是ViewGroup,继承自View,按道理来说应该是要先执行Layout的各个方法,然后有可能再传到子View中的,但从结果来看,它是直接跳到子View去执行的.有一种猜想就是事件先分发到子View中,有机会再传给Layout,但这和dispatchTouchEvent
的执行顺序相违背.所以这种猜想不成立.
查了一下资料,才发现ViewGroup还有另外一个方法
@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) { return super.onInterceptTouchEvent(ev);}
看一下它的源码,只有一行.
public boolean onInterceptTouchEvent(MotionEvent ev) { return false;}
从名字上可以看出这是用来判断是否截获事件的.我们试着让它返回true,看看会发生什么.
是不是跟第一篇博文的结果很像了,但又有一些不同.
- 多了一个
onInterceptTouchEvent
. - 惊喜的发现MainActivity的
onTouchEvent
也被执行到了. action up
直接就是跳过了CustomLayout中的方法.
当onInterceptTouchEvent
返回true的时候,事件被当前ViewGroup自己处理,不再往下分发事件.此时它自己的角色就是一个View了,执行View中相应的方法.
接着,将CustomLayout.java中onTouchEvent
的返回值super.onTouchEvent(event)
改为true
,再看一下结果
有没有发现MainActivity的onTouchEvent
又没了,而CustomLayout相应的方法又被执行了!我相信看到这里,你已经快崩溃了.如果只通过调试信息来做判断的话是很难得出正确结论的.所以这一部分还是留待下一次通过源码来分析吧.到时候再回过头来看就会觉得很清楚了,甚至遇到相似的问题不用再去看源码可以自己推导出来了.
End
这两篇博文看到现在,可能还是有很多人没看懂.但这两篇其实只是在为最后的源码分析做铺垫而已.同时,写了这两篇博文也让我自己梳理了一遍.相信我,最后一篇会尽可能的让大家明白的.
- Android学习笔记之事件分发机制(二)
- Android学习笔记之事件分发机制(一)
- Android 学习笔记之四 View的事件分发机制
- 笔记:事件分发机制(二):ViewGroup的事件分发
- 【Android学习】View点击事件分发机制(二)
- android学习笔记---事件分发机制(上)
- Android事件分发机制学习笔记
- Android事件分发机制学习笔记
- Android事件分发机制学习笔记
- Android事件分发机制---学习笔记
- Android学习笔记--事件分发机制
- Android View事件分发机制学习笔记
- Android ViewGroup事件分发机制学习笔记
- Android的事件分发机制(二)
- Android事件分发机制详解(二)
- Android----View事件分发机制(二)
- Android事件分发机制(二)
- android 事件分发机制详解(二)
- hdu 5319 2015多校对抗赛三
- 秒杀多线程第五篇 经典线程同步 关键段CS
- HDU 4336 Card Collector(概率DP)
- 查看ubuntu是32位还是64位
- 浅析notifyDataSetChanged内部工作流程
- Android学习笔记之事件分发机制(二)
- 2187 悼念512汶川大地震遇难同胞——老人是真饿了
- opencv图像边界的填充
- JAVA EE 自学路线
- waiting for xdebug session
- [UVA11572]Unique Snowflakes[构造]
- hdu5335 搜索+优化
- git之在远程开发分支上开发
- Hdu 5321 2015多校对抗赛三