Android Touch 事件的分发和消费机制
来源:互联网 发布:最大的建筑知乎 编辑:程序博客网 时间:2024/05/29 02:32
- Touch 事件的传递方式以及相关方法
Touch事件相关方法
功能
Activity
ViewGroup
View
public boolean dispatchTouchEvent(MotionEvent ev)
事件分发
Yes
Yes
Yes
public boolean onInterceptTouchEvent(MotionEvent ev)
事件拦截
No
Yes
No
public boolean onTouchEvent(MotionEvent ev)
事件响应
Yes
Yes
Yes
从上表中可以得出结论:Android中调用这个方法,用来传递和分发触摸事件,此方法返回值为布尔类型的值,通过返回true或false,来决定触摸事件是否向下传递。此外可以在子类重写dispatchTouchEvent方法,通过返回true或false来控制事件的分发和消费。(着重关注View和ViewGroup的事件分发的功能,下同)View 中事件的分发和ViewGroup事件的分发是有区别的,也就是两个类中的dispatchTouchEvent方法内容不一样。如果对此不太了解的可以参考郭霖大神的两边博客 Android事件分发机制完全解析,带你从源码的角度彻底理解(上)和Android事件分发机制完全解析,带你从源码的角度彻底理解(下),这两篇博客对view事件分发和viewGroup事件分发介绍的非常详细。
通过返回true或false,来判断在触摸事件传递过程中,是否拦截某个事件。从上表中可以看到,只有ViewGroup具有事件拦截的功能,ViewGroup源码中
onInterceptTouchEvent(MotionEvent ev)方法默认返回false,表示对所有的事件都不拦截。不过可以在ViewGroup的子类当中重写此方法,通过返回ture或false来判断触摸事件的拦截与否。- Touch事件
- Down:一次触摸事件的第一个MotionEvent对象,即手指初次接触屏幕。
- Up:通常为一次触摸事件的最后一个MotionEvent对象,即手指离开屏幕。
- Move:通常多次发生在一次触摸事件之中。表示触摸点发生了移动,我们通常把手指放到屏幕上,实际也会触发该事件,因为人手总是在轻微抖动的。
- Cancel:常用于取消某个触摸事件,一般是由程序逻辑来指定该事件,用于取消某次触摸事件。
- OutSide:当触摸点发生在响应事件的View之外时,传递的事件,通常由程序逻辑来指定。
- Touch 案例
- 情况1
dispatchTouchEvent
onInterceptTouchEvent
onTouchEvent
FatherLayout
return
super.dispatchTouchEvent(ev);
return
super.onInterceptTouchEvent(ev);
ChildLayout
return
super.dispatchTouchEvent(ev);
return
super.onInterceptTouchEvent(ev);
ChildButtonView
return
super.dispatchTouchEvent(ev);
连同连同Log日志用一张图来说明上述ACTION_DOWN触摸事件分发流程,如下:
情况1小结:
- 从Log日志可以看出,Touch事件先处理ACTION_DOWN事件,用于定位目标View,之后的move和up事件,都会在此view中处理。
- dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent都是调用父类方法得到的返回值,其中super.onInterceptTouchEvent(ev)默认返回false即不会拦截触摸事件。
- 因为 ChildButtonView继承自Button,重写的onTouchEvent方法中调用super.onTouchEvent(event)方法,默认接收并消费ACTION_DOWN事件,并返回true。即定位此View为目标View,后续的Move和Up事件,也会传到这里进行事件的处理。
- 情况2
dispatchTouchEvent
onInterceptTouchEvent
onTouchEvent
FatherLayout
return super.dispatchTouchEvent(ev);
return super.onInterceptTouchEvent(ev);
return super.onTouchEvent(event);ChildLayout
return super.dispatchTouchEvent(ev);
return super.onInterceptTouchEvent(ev);
return super.onTouchEvent(event);ChildButtonView
return super.dispatchTouchEvent(ev);
无return false
- 从Log日志可以看出,Touch事件仍旧是先处理ACTION_DOWN事件。
- ChildButtonView 重写的onTouchEvent方法中返回值为false,表示ChildButtonView 不会处理并消费该ACTION_DOWN事件
- 因为FatherLayout、ChildLayout重写的onTouchEvent方法中调用super.onTouchEvent(event)方法,因为相对布局默认不会消费ACTION_DOWN事件,所以会返回一个false,ACTION_DOWN事件此时会如紫色的箭头那样标示的一样继续向上传递,一直传到Activity中的OntouchEvent方法中。
- 情况3
dispatchTouchEvent
onInterceptTouchEvent
onTouchEvent
FatherLayout
return
super.dispatchTouchEvent(ev);
return
super.onInterceptTouchEvent(ev);
return true;ChildLayout
return
super.dispatchTouchEvent(ev);
return
super.onInterceptTouchEvent(ev);
return super.onTouchEvent(event);ChildButtonView
return
super.dispatchTouchEvent(ev);
无return false
- FatherLyout中OntouchEvent方法中,让其返回ture,表示有FatherLayout接收并消费ACTION_DOWN事件。后续的Move和up事件也会在此View中处理。
- 情况4
dispatchTouchEvent
onInterceptTouchEvent
onTouchEvent
FatherLayout
return super.dispatchTouchEvent(ev);
return super.onInterceptTouchEvent(ev);
ChildLayout
return super.dispatchTouchEvent(ev);
return super.onInterceptTouchEvent(ev);
ChildButtonView
return super.dispatchTouchEvent(ev);
- 情况5(主要讨论OnInterceptTouchEvent方法中的返回值,此时不在讨论onTouchEvent方法中的返回值)
dispatchTouchEvent
onInterceptTouchEvent
onTouchEvent
FatherLayout
return super.dispatchTouchEvent(ev);
return super.onInterceptTouchEvent(ev);
ChildLayout
return super.dispatchTouchEvent(ev);
return true;
ChildButtonView
return super.dispatchTouchEvent(ev);
- ChildLayout中重写的OnInteceptTouchEvent方法,返回值为true,表示会将该ACTION_DOWN拦截,不在向下进行传递,并且会将该ACTION_DOWN事件,交由自己调用onTouchEvent方法进行判断处理。
- 如果将FatherLayout中的OnInterceptTouchEvent方法返回值改为true,与情况5类似,不在进行详细分析。
- 情况6(主要讨论dispatchTouchEvent方法中的返回值,此时不在讨论onInterceptTouchEvent和onTouchEvent方法中的返回值)
dispatchTouchEvent
onInterceptTouchEvent
onTouchEvent
FatherLayout
return super.dispatchTouchEvent(ev);
return super.onInterceptTouchEvent(ev);
ChildLayout
return super.onInterceptTouchEvent(ev);
ChildButtonView
return ture;
- 如果在ChildButtonView重写的dispatchTouchEvent方法中,直接返回false,那么不会调用onTouchEvent方法。同样的在FatherLayout和ChildLayout中既不会调用onTouchEvent方法,也不会调用onInterceptTouchEvent方法。
- Android Touch事件分发和消费机制
- Android的Touch 事件的分发和消费机制
- touch事件的分发和消费机制
- Touch事件的分发和消费机制
- Touch 事件的分发和消费机制
- Touch 事件的分发和消费机制
- Touch 事件的分发和消费机制
- Android 编程下 Touch 事件的分发和消费机制
- Android 编程下 Touch 事件的分发和消费机制
- Android 编程下 Touch 事件的分发和消费机制
- Android 编程下 Touch 事件的分发和消费机制
- Android 编程下 Touch 事件的分发和消费机制
- Android 编程下 Touch 事件的分发和消费机制
- Android 编程下 Touch 事件的分发和消费机制
- Android 编程下 Touch 事件的分发和消费机制
- Android 编程下 Touch 事件的分发和消费机制
- Android 编程下 Touch 事件的分发和消费机制
- Android 编程下 Touch 事件的分发和消费机制
- 如何将文件映射到内存
- linux postfix邮件服务
- linux samba服务
- MySQL分配角色权限
- Hdu 6152 Friend-Graph(Ramsey定理)
- Android Touch 事件的分发和消费机制
- python网络编程
- 并发编程的三个概念
- Android中的线程和线程池
- Vector3.Lerp(When t = 0 returns a. When t = 1 returns b. When t = 0.5 returns the point midway betw)
- 深入理解操作系统虚拟内存
- Vector3.magnitude*vector3.up
- Linux GPIO Manipulation via Accessing Mapped Physical Memory
- PKG_CONFIG_PATH和PKG_CONFIG的路径设置问题