Android控件架构与自定义控件详解(四)——事件拦截机制分析
来源:互联网 发布:linux上如何卸载mysql 编辑:程序博客网 时间:2024/05/17 23:15
为了能够方便地了解事件拦截机制的整个流程,设计这样一个实例:
- MyViewGroupA——最外层的ViewGroup
- MyViewGroupB——中间的ViewGroup
- MyView——最底层的View
效果图如下:
代码只是重写了事件拦截和处理的几个方法,并给它们加上一些Log而已。
对于ViewGroup来说,重写了如下三个方法。
/** * 该方法虽然是事件分发的第一步,但一般情况下,我们不太会去改写这个方法 * @param ev * @return */ @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.d("xys", "ViewGroupA dispatchTouchEvent" + ev.getAction()); return super.dispatchTouchEvent(ev); } /** * 事件拦截的核心方法 * @param ev * @return */ @Override public boolean onInterceptTouchEvent(MotionEvent ev) { Log.d("xys", "ViewGroupA onInterceptTouchEvent" + ev.getAction()); return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { Log.d("xys", "ViewGroupA onTouchEvent" + event.getAction()); return super.onTouchEvent(event); }
对于View来说,重写了如下两个方法。
@Override public boolean onTouchEvent(MotionEvent event) { Log.d("xys", "View onTouchEvent" + event.getAction()); return super.onTouchEvent(event); } @Override public boolean dispatchTouchEvent(MotionEvent event) { Log.d("xys", "View dispatchTouchEvent" + event.getAction()); return super.dispatchTouchEvent(event); }
ViewGroup级别比较高,比View多了一个方法——onInterceptTouchEvent()方法。
(一)
我们先不修改任何返回值,运行程序后,点击一下MyView,Log日记记录如下:
05-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupA dispatchTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupA onInterceptTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupB dispatchTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupB onInterceptTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: View dispatchTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: View onTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupB onTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupA onTouchEvent0
可以看见,正常情况下,事件的传递顺序是:
MyViewGroupA——>MyViewGroupB——>MyView。事件传递的时候,执行dispatchTouchEvent()方法,再执行onInterceptTouchEvent()方法。
事件的处理顺序是:
MyView——>MyViewGroupB——>MyViewGroupA。事件处理都是执行onTouchEvent()方法。
事件传递的返回值非常容易理解:true,拦截,不继续;false,不拦截,继续流程。
事件处理的返回值也类似:true,处理了;false, 给父ViewGroup处理。
初始情况下,返回值都是false。
(二)
如果我们让MyViewGroupA把事件拦截了,即让MyViewGroupA的onInterceptTouchEvent()方法返回true,Log日志如下:
05-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupA dispatchTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupA onInterceptTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupA onTouchEvent0
MyViewGroupA把所有的事都干了,也就没有后面的人的事了。
(三)
再比如我们让MyViewGroupB把事件拦截了,即让MyViewGroupB的onInterceptTouchEvent()方法返回true,Log日志如下:
05-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupA dispatchTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupA onInterceptTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupB dispatchTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupB onInterceptTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupB onTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupA onTouchEvent0
MyViewGroupB把事情干了,MyView就不用干活了。
(四)
在事件的处理中,最开始时MyView把事情干完了,需要向父布局报告,所以MyView的事件处理返回false,但若MyView的onTouchEvent()方法返回true,再看看Log日志:
05-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupA dispatchTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupA onInterceptTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupB dispatchTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupB onInterceptTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: View dispatchTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: View onTouchEvent0
看以看到,事件传递和以前一样,但是事件处理,到MyView这就结束了,因为MyView返回true,表示不用向父布局汇报了。
(五)
若MyViewGroupB的onTouchEvent()方法返回true,整个事件也就到此为止了,Log日志如下:
05-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupA dispatchTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupA onInterceptTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupB dispatchTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupB onInterceptTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: View dispatchTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: View onTouchEvent005-15 19:15:24.730 31442-31442/com.imooc.viewlayout D/xys: ViewGroupB onTouchEvent0
代码地址
- Android控件架构与自定义控件详解(四)——事件拦截机制分析
- Android控件架构与自定义控件详解(四)事件拦截机制分析
- Android 控件架构与自定义控件(四)
- Android控件架构与自定义控件详解(一)——Android控件架构与View的绘制原理
- Android控件架构与自定义控件详解(二)——自定义View
- Android控件架构与自定义控件详解(三)——自定义ViewGroup
- Android控件架构与自定义控件详解
- Android控件架构与自定义控件详解
- Android控件架构与自定义控件详解
- Android 控件架构与自定义控件详解
- 3.5.Android控件架构与自定义控件详解之自定义View(四)
- Android群英传知识点回顾——第三章:Android控件架构与自定义控件详解
- 《Android群英传》阅读笔记——第三章:Android控件架构与自定义控件详解
- Android群英传学习——第三章、Android控件架构与自定义控件详解
- Android控件构架与自定义控件详解(一)Android控件架构与自定义控件绘制原理
- Android群英传学习——控件架构与自定义控件
- Android绘图机制(四)自定义控件
- Android绘图机制(四)自定义控件
- 简单立体几何和DP的结合
- HDU 1052田忌赛马 贪心+动态数组
- ANDROID开发笔记(三)在ANDROID中安装OPENCV
- JavaIO系统
- WampServer 2.5设置外网访问/局域网手机访问(403 Forbidden错误解决方法)
- Android控件架构与自定义控件详解(四)——事件拦截机制分析
- [POJ2262]Goldbach's Conjecture
- asp.net 学习记录3
- 如何使用Apktool
- 如何在不影响原有aapt源码的情况下编译定制版aapt
- 337_house_robber_III
- 百度之星——Problem D
- Gson的使用
- 报错:GenerateSource 任务意外失败:未将对象引用设置到对象的实例