android事件分发那些事~
来源:互联网 发布:淘宝服装品牌排行榜 编辑:程序博客网 时间:2024/05/15 07:58
百度”android事件分发”一堆文章,都是围绕dispatchTouchEvent,onInterceptTouchEvent,onTouchEvent三个方法开始讨论源码的,看书也很难理解,而且容易忘记,尤其一些理论的,所以今天我们不分析源码,简单粗暴的动手实践去探索下它.
首先我们需要准备一些东西:
- 3个自定义ViewGroup(ViewGroup1,ViewGroup2,ViewGroup3),看到自定义别慌,就是继承下ViewGroup,就这么粗暴.
- 1个自定义View,和上面一样粗暴.
- 1个Activity,自动生成就行,只需要改下xml布局.
ps:这里我多说一句,这里用RelativeLayout,LinearLayout什么的都是可以的,反正它们的爸爸都是ViewGroup,ViewGroup的爸爸是View,自定义是为了重写dispatchTouchEvent,onInterceptTouchEvent,onTouchEvent从而打印日志,方便我们观察,不过自定义View没有onInterceptTouchEvent方法.
下面来布局我们的xml布局,就是叠罗汉式的,从下到上依次是ViewGroup1,ViewGroup2,ViewGroup3,View.
代码(这里是ViewGroup1的代码,其他的改改日志就好):
@Override public boolean dispatchTouchEvent(MotionEvent ev) { int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: Log.e("Debug", "MyViewGroup1:dispatchTouchEvent ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: Log.e("Debug", "MyViewGroup1:dispatchTouchEvent ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e("Debug", "MyViewGroup1:dispatchTouchEvent ACTION_UP"); break; default: break; } boolean dispatchTouchEvent = super.dispatchTouchEvent(ev); Log.e("Debug", "MyViewGroup1:super.dispatchTouchEvent(ev)" + dispatchTouchEvent); return dispatchTouchEvent; } @Override public boolean onInterceptTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: Log.e("Debug", "MyViewGroup1:onInterceptTouchEvent ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: Log.e("Debug", "MyViewGroup1:onInterceptTouchEvent ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e("Debug", "MyViewGroup1:onInterceptTouchEvent ACTION_UP"); break; default: break; } boolean onInterceptTouchEvent = super.onInterceptTouchEvent(event); Log.e("Debug", "MyViewGroup1:super.onInterceptTouchEvent(event)" + onInterceptTouchEvent); return onInterceptTouchEvent; } @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: Log.e("Debug", "MyViewGroup1:onTouchEvent ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: Log.e("Debug", "MyViewGroup1:onTouchEvent ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e("Debug", "MyViewGroup1:onTouchEvent ACTION_UP"); break; default: break; } boolean onTouchEvent = super.onTouchEvent(event); Log.e("Debug", "MyViewGroup1:super.onTouchEvent(event)" + onTouchEvent); return onTouchEvent; }
布局文件(这里注意下,MyView里需要添加android:clickable=”true”,自定义view默认是不可点击的,button这类的默认是可以点击的)
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <com.wjy.app.test.MyViewGroup1 android:layout_width="match_parent" android:layout_height="match_parent"> <com.wjy.app.test.MyViewGroup2 android:layout_width="match_parent" android:layout_height="match_parent"> <com.wjy.app.test.MyViewGroup3 android:layout_width="match_parent" android:layout_height="match_parent"> <com.wjy.app.test.MyView android:id="@+id/my_view" android:layout_width="300dp" android:layout_height="300dp" android:background="@android:color/holo_blue_bright" android:clickable="true" /> </com.wjy.app.test.MyViewGroup3> </com.wjy.app.test.MyViewGroup2> </com.wjy.app.test.MyViewGroup1></RelativeLayout>
测试还有三十秒到达战场,碾碎它们.一顿控制变量法操作,操作的就是三个方法的boolean返回值,然后我们轻轻的点击MyView.
dispatchTouchEvent方法
E/Debug: MyViewGroup1:dispatchTouchEvent ACTION_DOWNE/Debug: MyViewGroup1:onInterceptTouchEvent ACTION_DOWNE/Debug: MyViewGroup1:super.onInterceptTouchEvent(event)falseE/Debug: MyViewGroup2:dispatchTouchEvent ACTION_DOWNE/Debug: MyViewGroup2:onInterceptTouchEvent ACTION_DOWNE/Debug: MyViewGroup2:super.onInterceptTouchEvent(event)falseE/Debug: MyViewGroup3:dispatchTouchEvent ACTION_DOWNE/Debug: MyViewGroup3:onInterceptTouchEvent ACTION_DOWNE/Debug: MyViewGroup3:super.onInterceptTouchEvent(event)falseE/Debug: MyView:dispatchTouchEvent ACTION_DOWNE/Debug: MyView:onTouchEvent ACTION_DOWNE/Debug: MyView:super.onTouchEvent(event)trueE/Debug: MyView:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup3:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup2:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup1:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup1:dispatchTouchEvent ACTION_MOVEE/Debug: MyViewGroup1:onInterceptTouchEvent ACTION_MOVEE/Debug: MyViewGroup1:super.onInterceptTouchEvent(event)falseE/Debug: MyViewGroup2:dispatchTouchEvent ACTION_MOVEE/Debug: MyViewGroup2:onInterceptTouchEvent ACTION_MOVEE/Debug: MyViewGroup2:super.onInterceptTouchEvent(event)falseE/Debug: MyViewGroup3:dispatchTouchEvent ACTION_MOVEE/Debug: MyViewGroup3:onInterceptTouchEvent ACTION_MOVEE/Debug: MyViewGroup3:super.onInterceptTouchEvent(event)falseE/Debug: MyView:dispatchTouchEvent ACTION_MOVEE/Debug: MyView:onTouchEvent ACTION_MOVEE/Debug: MyView:super.onTouchEvent(event)trueE/Debug: MyView:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup3:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup2:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup1:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup1:dispatchTouchEvent ACTION_UPE/Debug: MyViewGroup1:onInterceptTouchEvent ACTION_UPE/Debug: MyViewGroup1:super.onInterceptTouchEvent(event)falseE/Debug: MyViewGroup2:dispatchTouchEvent ACTION_UPE/Debug: MyViewGroup2:onInterceptTouchEvent ACTION_UPE/Debug: MyViewGroup2:super.onInterceptTouchEvent(event)falseE/Debug: MyViewGroup3:dispatchTouchEvent ACTION_UPE/Debug: MyViewGroup3:onInterceptTouchEvent ACTION_UPE/Debug: MyViewGroup3:super.onInterceptTouchEvent(event)falseE/Debug: MyView:dispatchTouchEvent ACTION_UPE/Debug: MyView:onTouchEvent ACTION_UPE/Debug: MyView:super.onTouchEvent(event)trueE/Debug: MyView:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup3:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup2:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup1:super.dispatchTouchEvent(ev)true
结论: Android事件分发顺序是先到ViewGroup层,在传递到View层(如上图从最底层开始传递)。
onInterceptTouchEvent方法
//ViewGroup1 中 onInterceptTouchEvent返回trueE/Debug: MyViewGroup1:dispatchTouchEvent ACTION_DOWNE/Debug: MyViewGroup1:onInterceptTouchEvent ACTION_DOWNE/Debug: MyViewGroup1:onTouchEvent ACTION_DOWNE/Debug: MyViewGroup1:super.onTouchEvent(event)falseE/Debug: MyViewGroup1:super.dispatchTouchEvent(ev)false//ViewGroup2 中 onInterceptTouchEvent返回trueE/Debug: MyViewGroup1:dispatchTouchEvent ACTION_DOWNE/Debug: MyViewGroup1:onInterceptTouchEvent ACTION_DOWNE/Debug: MyViewGroup1:super.onInterceptTouchEvent(event)falseE/Debug: MyViewGroup2:dispatchTouchEvent ACTION_DOWNE/Debug: MyViewGroup2:onInterceptTouchEvent ACTION_DOWNE/Debug: MyViewGroup2:onTouchEvent ACTION_DOWNE/Debug: MyViewGroup2:super.onTouchEvent(event)falseE/Debug: MyViewGroup2:super.dispatchTouchEvent(ev)falseE/Debug: MyViewGroup1:onTouchEvent ACTION_DOWNE/Debug: MyViewGroup1:super.onTouchEvent(event)falseE/Debug: MyViewGroup1:super.dispatchTouchEvent(ev)false
结论:在ViewGroup中onInterceptTouchEvent方法对事件传递进行拦截,返回值true代表不允许事件继续向子View传递,反之继续传递。
onTouchEvent方法
//MyView 中 onTouchEvent 返回 trueE/Debug: MyViewGroup1:dispatchTouchEvent ACTION_DOWNE/Debug: MyViewGroup1:onInterceptTouchEvent ACTION_DOWNE/Debug: MyViewGroup1:super.onInterceptTouchEvent(event)falseE/Debug: MyViewGroup2:dispatchTouchEvent ACTION_DOWNE/Debug: MyViewGroup2:onInterceptTouchEvent ACTION_DOWNE/Debug: MyViewGroup2:super.onInterceptTouchEvent(event)falseE/Debug: MyViewGroup3:dispatchTouchEvent ACTION_DOWNE/Debug: MyViewGroup3:onInterceptTouchEvent ACTION_DOWNE/Debug: MyViewGroup3:super.onInterceptTouchEvent(event)falseE/Debug: MyView:dispatchTouchEvent ACTION_DOWNE/Debug: MyView:onTouchEvent ACTION_DOWNE/Debug: MyView:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup3:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup2:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup1:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup1:dispatchTouchEvent ACTION_MOVEE/Debug: MyViewGroup1:onInterceptTouchEvent ACTION_MOVEE/Debug: MyViewGroup1:super.onInterceptTouchEvent(event)falseE/Debug: MyViewGroup2:dispatchTouchEvent ACTION_MOVEE/Debug: MyViewGroup2:onInterceptTouchEvent ACTION_MOVEE/Debug: MyViewGroup2:super.onInterceptTouchEvent(event)falseE/Debug: MyViewGroup3:dispatchTouchEvent ACTION_MOVEE/Debug: MyViewGroup3:onInterceptTouchEvent ACTION_MOVEE/Debug: MyViewGroup3:super.onInterceptTouchEvent(event)falseE/Debug: MyView:dispatchTouchEvent ACTION_MOVEE/Debug: MyView:onTouchEvent ACTION_MOVEE/Debug: MyView:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup3:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup2:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup1:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup1:dispatchTouchEvent ACTION_UPE/Debug: MyViewGroup1:onInterceptTouchEvent ACTION_UPE/Debug: MyViewGroup1:super.onInterceptTouchEvent(event)falseE/Debug: MyViewGroup2:dispatchTouchEvent ACTION_UPE/Debug: MyViewGroup2:onInterceptTouchEvent ACTION_UPE/Debug: MyViewGroup2:super.onInterceptTouchEvent(event)falseE/Debug: MyViewGroup3:dispatchTouchEvent ACTION_UPE/Debug: MyViewGroup3:onInterceptTouchEvent ACTION_UPE/Debug: MyViewGroup3:super.onInterceptTouchEvent(event)falseE/Debug: MyView:dispatchTouchEvent ACTION_UPE/Debug: MyView:onTouchEvent ACTION_UPE/Debug: MyView:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup3:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup2:super.dispatchTouchEvent(ev)trueE/Debug: MyViewGroup1:super.dispatchTouchEvent(ev)true
结论:如果这里把ViewGroup1或者2的onTouchEvent方法返回true,打印出来和上面的日志是一样的,why?这里需要借助源码解释了,只要被view消耗了onTouchEvent事件,那么ViewGroup将无法收到该事件.
眼过千遍不如手过一遍,看再多的理论自己实践才是王道.
小弟的功力有限,这里推荐郭霖大神分析源码地址:http://blog.csdn.net/guolin_blog/article/details/9097463
1 0
- android事件分发那些事~
- Android触摸事件分发那些事
- 2.Android应用分发那些事
- android事件分发
- android 事件分发
- android事件分发
- android事件分发机制
- Android 事件分发
- Android事件分发机制
- Android 事件分发机制
- Android事件分发机制
- android事件分发
- Android事件的分发
- Android 事件分发机制
- android事件的分发
- Android 事件分发机制
- android 事件分发机制
- Android事件分发机制
- Java中使用Protocol Buffer
- WITH GRANT OPTION的作用
- Yahoo军规学习笔记
- 回归测试简介
- jquery为select添加option的代码探讨
- android事件分发那些事~
- Spring与Quartz的整合实现定时任务调度
- 【低功耗架构开发系列】(一)云服务选型
- 数据结构与算法(12)Fibonacci查找
- 小探正则
- C#数组的合并拆分
- Qt在Windows下的三种编程环境搭建
- 在页面上生成二维码
- oracle锁