android 事件传递机制(1)
在项目中,经常遇到事件冲突,ScrollView,ViewPager滑动卡顿等情况,比如:onClick和onLongClick事件冲突,dispatchTouchEvent,onInterceptTouchEvent这些方法都有一个boolean返回值,不同返回值事件处理机制是不同的。
一:事件分发流程
1:现在有一个场景,用户长按button,我们希望只触发onLongClick,然而onClick事件也触发了.

这种情况比如简单,直接在onLongClick返回true就可以解决了,返回true表示onLongClick消费了这次事件。
2:view 和 viewGroup的介绍
View是所有UI组件的基类(如:TextView,Button,ImageView),而 ViewGroup是容纳这些组件的容器(如:LinearLayout,ReltiveLayout),ViewGroup是View派生出来的.
view有dispatchTouchEvent,onTouchEvent这两个方法,ViewGroup多了一个onInterceptTouchEvent方法,此方法决定触发事件是自己处理,还是分发给下一个组件处理.
2:事件涉及到的常用方法
用户点击屏幕时,将触发viewGroup的dispatchTouchEvent(MotionEvent ev)、onInterceptTouchEvent(MotionEvent ev)、onTouchEvent(MotionEvent ev);
3:方法返回值介绍
dispatchTouchEvent是处理触摸事件分发,事件(多数情况)是从Activity的dispatchTouchEvent开始的。执行super.dispatchTouchEvent(ev),事件向下分发。
onInterceptTouchEvent是ViewGroup提供的方法,默认返回false,返回true表示拦截,返回true后,由该类的onTouchEvent方法来执行。
onTouchEvent是View中提供的方法,ViewGroup也有这个方法,view中不提供onInterceptTouchEvent。view中默认返回true,表示消费了这个事件。
二:举一个栗子
1 老板将一个任务分配给经理,经理将任务分配给员工去完成,员工完成后,将结果反馈给经理,经理将任务结果反馈给老板,这是默认流程。

默认流程dispatchTouchEvent(MotionEvent ev)、onInterceptTouchEvent(MotionEvent ev)、onTouchEvent(MotionEvent ev),全部返回super.xxxxxxx

输出日志的结果
10-15 20:13:31.600 8716-8716/com.activity E/info: BossView dispatchTouchEvent() boss create task!
10-15 20:13:31.600 8716-8716/com.activity E/info: BossView onInterceptTouchEvent() boss将task 分配给manager
10-15 20:13:31.600 8716-8716/com.activity I/info: ManagerView 经理让onInterceptTouchEvent决定任务由谁完成
10-15 20:13:31.600 8716-8716/com.activity I/info: ManagerView onInterceptTouchEvent()经理接收到任务,将任务分配给员工
10-15 20:13:31.601 8716-8716/com.activity I/info: EmployeesView 员工开始工作.
10-15 20:13:31.601 8716-8716/com.activity I/info: EmployeesView 员工圆满完成任务.
10-15 20:13:31.602 8716-8716/com.activity I/info: ManagerView onTouchEvent() 经理验收任务结果,并向老板报告
10-15 20:13:31.602 8716-8716/com.activity E/info: BossView onTouchEvent() 工作已经完毕
2 老板将一个任务分配给经理,经理将任务分配给员工去完成,员工觉得难度大,无法完成(onTouchEvent返回true),由于老板没有接收到工作报告,会不停向经理分发任务(managerView的dispatchTouchEvent方法将不停被调用,员工的dispatchTouchEvent方法也会被继续调用)。

输出日志:

3 老板将一个任务分配给经理,因为上一次任务,经理并未收到员工的工作报告,所以这次经理决定,自己的来本次完成,将事件直接消费(onInterceptTouchEvent返回true),不分给员工去做,让员工一边凉快去 。

日志输出:
10-15 22:11:26.877 22219-22219/com.activity I/info: MainActivity--dispatchTouchEvent()ACTION_DOWN
10-15 22:11:26.878 22219-22219/com.activity E/info: BossView dispatchTouchEvent() boss create task!
10-15 22:11:26.879 22219-22219/com.activity E/info: BossView onInterceptTouchEvent() boss将task 分配给manager
10-15 22:11:26.879 22219-22219/com.activity I/info: ManagerView 经理让onInterceptTouchEvent决定任务由谁完成
10-15 22:11:26.879 22219-22219/com.activity I/info: ManagerView onInterceptTouchEvent()经理接收到任务安排,员工做得不好,自己来做任务
10-15 22:11:26.879 22219-22219/com.activity I/info: ManagerView onTouchEvent() 经理验收任务结果,并向老板报告
10-15 22:11:26.879 22219-22219/com.activity E/info: BossView onTouchEvent() 工作已经完毕
10-15 22:11:26.886 22219-22219/com.activity I/info: MainActivity--dispatchTouchEvent()ACTION_MOVE
10-15 22:11:26.902 22219-22219/com.activity I/info: MainActivity--dispatchTouchEvent()ACTION_MOVE
10-15 22:11:26.912 22219-22219/com.activity I/info: MainActivity--dispatchTouchEvent()ACTION_MOVE
10-15 22:11:26.919 22219-22219/com.activity I/info: MainActivity--dispatchTouchEvent()ACTION_MOVE
10-15 22:11:26.921 22219-22219/com.activity I/info: MainActivity--dispatchTouchEvent()ACTION_UP
三:代码
由于代码差不多,这里只贴出ManagerView的代码,完整代码下载连接在文章下方
public class ManagerView extends LinearLayout {
private final String TAG="ManagerView ";
private int index=0;
public ManagerView(Context context) {
super(context);
}
public ManagerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if(index==0){
Log.i("info",TAG+" onTouchEvent() 经理验收任务结果,并向老板报告");
}else{
Log.i("info",TAG+" onTouchEvent() 自己亲自来完成任务");
}
return super.onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
index = 0;
// if(index==0){
// Log.i("info",TAG+"onInterceptTouchEvent()经理接收到任务,将任务分配给员工");
// return super.onInterceptTouchEvent(ev);
// }else{
Log.i("info",TAG+"onInterceptTouchEvent()经理接收到任务安排,员工做得不好,自己来做任务");
return true;
// }
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.i("info",TAG+"经理让onInterceptTouchEvent决定任务由谁完成");
return super.dispatchTouchEvent(ev);
}
}
备注:上传代码时,我电脑github出了点小问题,如果代码有问题,请留言,代码下载地址:github
android 事件传递机制(1)的更多相关文章
- Android事件传递机制(转)
Android事件构成 在Android中,事件主要包括点按.长按.拖拽.滑动等,点按又包括单击和双击,另外还包括单指操作和多指操作.所有这些都构成了Android中的事件响应.总的来说,所有的事件都 ...
- Android事件传递机制详解及最新源码分析——ViewGroup篇
版权声明:本文出自汪磊的博客,转载请务必注明出处. 在上一篇<Android事件传递机制详解及最新源码分析--View篇>中,详细讲解了View事件的传递机制,没掌握或者掌握不扎实的小伙伴 ...
- Android事件传递机制详解及最新源码分析——View篇
摘要: 版权声明:本文出自汪磊的博客,转载请务必注明出处. 对于安卓事件传递机制相信绝大部分开发者都听说过或者了解过,也是面试中最常问的问题之一.但是真正能从源码角度理解具体事件传递流程的相信并不多, ...
- Android事件传递机制详解及最新源码分析——Activity篇
版权声明:本文出自汪磊的博客,转载请务必注明出处. 在前两篇我们共同探讨了事件传递机制<View篇>与<ViewGroup篇>,我们知道View触摸事件是ViewGroup传递 ...
- Android事件传递机制总结
Android中控件的分类 Activity dispatchTouchEvent(MotionEvent e) onTouchEvent(MotionEvent e) ViewGroup(View) ...
- Android事件传递机制
http://blog.csdn.net/awangyunke/article/details/22047987 1)public boolean dispatchTouchEvent(MotionE ...
- android事件传递机制以及onInterceptTouchEvent()和onTouchEvent()总结
老实说,这两个小东东实在是太麻烦了,很不好懂,我自己那api文档都头晕,在网上找到很多资料,才知道是怎么回事,这里总结一下,记住这个原则就会很清楚了: 1.onInterceptTouchEvent( ...
- android事件传递机制以及onInterceptTouchEvent()和onTouchEvent()详解二之小秘与领导的故事
总结的不是很好,自己也有点看不懂,正好现在用到了,研究了一个,再次总结,方便大家查看 总则: 1.onInterceptTouchEvent中有个Intercept,这是什么意思呢?她叫拦截,你大概知 ...
- android 事件传递机制
有三个方法: dispatchTouchEvent onInterceptTouchEvent onTouchEvent 首先:A的dispatchTouchEvent-A的onInterceptTo ...
随机推荐
- 基础教程:ASP.NET Core 2.0 MVC筛选器
问题 如何在ASP.NET Core的MVC请求管道之前和之后运行代码. 解 在一个空的项目中,更新 Startup 类以添加MVC的服务和中间件. publicvoid ConfigureServi ...
- Linux下gcc编译生成动态链接库*.so文件并调用它
动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记,也为其它正为动态库链接库而苦恼的兄弟们提供一 ...
- shell的逻辑运算符
一.逻辑运算符 逻辑卷标 表示意思 1. 关于档案与目录的侦测逻辑卷标! -f 常用!侦测『档案』是否存在 eg: if [ -f filename ] -d 常用!侦测『目录』是否存在 -b 侦测是 ...
- 解决弹出蒙层滑动穿透问题-vue
最近开发过程中遇到一些小问题(似乎问题总是那么多),但一直没什么时间去优化与解决.程序员不能被业务绑架,有时间还是花点在代码上
- MyBatis开发学习记录
使用MyBatis时主要是完成POJO和SQL的映射规则 MyBatis基本构成: SqlSessionFactoryBuilder SqlSessionFactory SqlSession SqlM ...
- Pyhton编程(五)之基本数据类型-列表、元组、字典
一:列表(list) 列表是由一系列按特定顺序排列的元素组成,可以创建包含字母表中的所有字母.数字.或中文的列表,也可以将任何东西加入列表中,其中的元素之间可以没有任何关系. 在Python中,用方括 ...
- wamp环境下如何安装redis扩展
Redis安装 wamp环境安装redis扩展 首先在自己本地项目中phpinfo(); 查看php版本; (php版本是5.5, ts-vcll表示MSVC11 (Visual C++ 2012), ...
- [ 面试没回答上的问题2]IOS上给body绑定click事件的bug
面试被问到ios上的bug,自己提到绑定click事件的bug,但是并没有把问题讲的很清楚,这里再清理一下思路. 这个bug只在IOS上有,包括ihone,ipad,由于ios浏览器都用的safari ...
- log4net使用注意事项
1配置Log4net Log4net的配置文件有几种使用方式,这里将配置log4net的部分独立出来,即关于log4net的配置独立成文件log4net.config. 1)写入Mysql log4n ...
- linux grep 从入门到精通
linux grep 从入门到精通 一.初级 搜索日志 grep "186" catalina.out 在新输出日志中监听固定字符串 tail -f catalina.out | ...