android 滑动事件冲突解决 Touch事件处理机制
2015-12-24 15:35
639 查看
》要不要拦截当前的按键以及触摸事件??
..触摸事件是由Linux内核的一个Input子系统来管理的(InputManager),Linux子系统会在
Android系统的一个系统Service:
..
WindowState,通过IWindow代理将此消息发送到IWindow服务端(IWindow.Stub子类),这个IWindow.Stub属于ViewRoot(这个类继承Handler,主要用于连接PhoneWindow和WindowManagerService),所以事件就传到了ViewRoot.dispatchPointer()中.
..Event事件是首先到了
PhoneWindow 的 DecorView 的 dispatchTouchEvent 方法,此方法通过 CallBack 调用了 Activity 的 dispatchTouchEvent 方法,在 Activity 这里,我们可以重写 Activity 的dispatchTouchEvent 方法阻断 touch事件的传播。接着在Activity里的dispatchTouchEvent 方法里,事件又再次传递到DecorView,DecorView通过调用父类(ViewGroup)的dispatchTouchEvent
将事件传给父类处理,也就是我们下面要分析的方法,这才进入网上大部分文章讲解的touch事件传递流程。
..用户点击屏幕产生Touch(包括DOWN、UP、MOVE,本文分析的是DOWN)事件
-> InputManager -> WindowManagerService.dispatchPointer() -> IWindow.Stub -> ViewRoot.dispatchPointer() -> PhoneWindow.DecorView.dispatchTouchEvent() -> Activity.dispatchTouchEvent() -> PhoneWindow.superDispatchTouchEvent -> PhoneWindow.DecorView.superDispatchTouchEvent
-> ViewGroup.dispatchTouchEvent() -> ViewGroup.dispatchTransformedTouchEvent() -> 子View.dispatchTouchEvent() -> 子View.onTouch() -> 子View.onTouchEvent() -> 事件被消费结束。(这个过程是由上往下传导)
》android中的事件类型分为按键事件和屏幕触摸事件,Touch事件是屏幕触摸事件的基础事件,有必要对它进行深入的了解。
一个最简单的屏幕触摸动作触发了一系列Touch事件:ACTION_DOWN->ACTION_MOVE->ACTION_MOVE->ACTION_MOVE...->ACTION_MOVE->ACTION_UP
当屏幕中包含一个ViewGroup,而这个ViewGroup又包含一个子view,这个时候android系统如何处理Touch事件呢?到底是ViewGroup来处理Touch事件,还是子view来处理Touch事件呢?我只能很肯定的对你说不一定。呵呵,为什么呢?看看下面我的调查结果你就明白了。
android系统中的每个View的子类都具有下面三个和TouchEvent处理密切相关的方法:
1)public boolean dispatchTouchEvent(MotionEvent ev) 这个方法用来分发TouchEvent
2)public boolean onInterceptTouchEvent(MotionEvent ev) 这个方法用来拦截TouchEvent
3)public boolean onTouchEvent(MotionEvent ev) 这个方法用来处理TouchEvent
当TouchEvent发生时,首先Activity将TouchEvent传递给最顶层的View, TouchEvent最先到达最顶层 view 的 dispatchTouchEvent ,然后由 dispatchTouchEvent 方法进行分发,如果dispatchTouchEvent返回true ,则交给这个view的onTouchEvent处理,如果dispatchTouchEvent返回
false ,则交给这个 view 的 interceptTouchEvent 方法来决定是否要拦截这个事件,如果 interceptTouchEvent 返回 true ,也就是拦截掉了,则交给它的 onTouchEvent 来处理,如果 interceptTouchEvent 返回 false ,那么就传递给子 view ,由子 view 的 dispatchTouchEvent 再来开始这个事件的分发。如果事件传递到某一层的子 view 的 onTouchEvent 上了,这个方法返回了 false
,那么这个事件会从这个 view 往上传递,都是 onTouchEvent 来接收。而如果传递到最上面的 onTouchEvent 也返回 false 的话,这个事件就会“消失”,而且接收不到下一次事件。
让子先处理的方法是 从写父的onInterceptTouchEvent事件并返回false
public boolean onInterceptTouchEvent(MotionEvent ev) {
return false;
}
>
1、基础知识
(1) 所有Touch事件都被封装成了MotionEvent对象,包括Touch的位置、时间、历史记录以及第几个手指(多指触摸)等。
(2) 事件类型分为ACTION_DOWN, ACTION_UP, ACTION_MOVE, ACTION_POINTER_DOWN, ACTION_POINTER_UP, ACTION_CANCEL,每个事件都是以ACTION_DOWN开始ACTION_UP结束。
(3) 对事件的处理包括三类,分别为传递——dispatchTouchEvent()函数、拦截——onInterceptTouchEvent()函数、消费——onTouchEvent()函数和OnTouchListener
2、传递流程
(1) 事件从Activity.dispatchTouchEvent()开始传递,只要没有被停止或拦截,从最上层的View(ViewGroup)开始一直往下(子View)传递。子View可以通过onTouchEvent()对事件进行处理。
(2) 事件由父View(ViewGroup)传递给子View,ViewGroup可以通过onInterceptTouchEvent()对事件做拦截,停止其往下传递。
(3) 如果事件从上往下传递过程中一直没有被停止,且最底层子View没有消费事件,事件会反向往上传递,这时父View(ViewGroup)可以进行消费,如果还是没有被消费的话,最后会到Activity的onTouchEvent()函数。
(4) 如果View没有对ACTION_DOWN进行消费,之后的其他事件不会传递过来。
(5) OnTouchListener优先于onTouchEvent()对事件进行消费。
上面的消费即表示相应函数返回值为true。
> Android 中与 Touch 事件相关的方法包括:dispatchTouchEvent(MotionEvent ev)、onInterceptTouchEvent(MotionEvent ev)、onTouchEvent(MotionEvent
ev);能够响应这些方法的控件包括:ViewGroup、View、Activity。方法与控件的对应关系如下表所示:
..触摸事件是由Linux内核的一个Input子系统来管理的(InputManager),Linux子系统会在
/dev/input/这个路径下创建硬件输入设备节点(这里的硬件设备就是我们的触摸屏了)。当手指触动触摸屏时,硬件设备通过设备节点像内核(其实是InputManager管理)报告事件,
InputManager经过处理将此事件传给
Android系统的一个系统Service:
WindowManagerService。
..
WindowManagerService调用dispatchPointer()从存放WindowState的z-order顺序列表中找到能接收当前touch事件的
WindowState,通过IWindow代理将此消息发送到IWindow服务端(IWindow.Stub子类),这个IWindow.Stub属于ViewRoot(这个类继承Handler,主要用于连接PhoneWindow和WindowManagerService),所以事件就传到了ViewRoot.dispatchPointer()中.
..Event事件是首先到了
PhoneWindow 的 DecorView 的 dispatchTouchEvent 方法,此方法通过 CallBack 调用了 Activity 的 dispatchTouchEvent 方法,在 Activity 这里,我们可以重写 Activity 的dispatchTouchEvent 方法阻断 touch事件的传播。接着在Activity里的dispatchTouchEvent 方法里,事件又再次传递到DecorView,DecorView通过调用父类(ViewGroup)的dispatchTouchEvent
将事件传给父类处理,也就是我们下面要分析的方法,这才进入网上大部分文章讲解的touch事件传递流程。
..用户点击屏幕产生Touch(包括DOWN、UP、MOVE,本文分析的是DOWN)事件
-> InputManager -> WindowManagerService.dispatchPointer() -> IWindow.Stub -> ViewRoot.dispatchPointer() -> PhoneWindow.DecorView.dispatchTouchEvent() -> Activity.dispatchTouchEvent() -> PhoneWindow.superDispatchTouchEvent -> PhoneWindow.DecorView.superDispatchTouchEvent
-> ViewGroup.dispatchTouchEvent() -> ViewGroup.dispatchTransformedTouchEvent() -> 子View.dispatchTouchEvent() -> 子View.onTouch() -> 子View.onTouchEvent() -> 事件被消费结束。(这个过程是由上往下传导)
》android中的事件类型分为按键事件和屏幕触摸事件,Touch事件是屏幕触摸事件的基础事件,有必要对它进行深入的了解。
一个最简单的屏幕触摸动作触发了一系列Touch事件:ACTION_DOWN->ACTION_MOVE->ACTION_MOVE->ACTION_MOVE...->ACTION_MOVE->ACTION_UP
当屏幕中包含一个ViewGroup,而这个ViewGroup又包含一个子view,这个时候android系统如何处理Touch事件呢?到底是ViewGroup来处理Touch事件,还是子view来处理Touch事件呢?我只能很肯定的对你说不一定。呵呵,为什么呢?看看下面我的调查结果你就明白了。
android系统中的每个View的子类都具有下面三个和TouchEvent处理密切相关的方法:
1)public boolean dispatchTouchEvent(MotionEvent ev) 这个方法用来分发TouchEvent
2)public boolean onInterceptTouchEvent(MotionEvent ev) 这个方法用来拦截TouchEvent
3)public boolean onTouchEvent(MotionEvent ev) 这个方法用来处理TouchEvent
当TouchEvent发生时,首先Activity将TouchEvent传递给最顶层的View, TouchEvent最先到达最顶层 view 的 dispatchTouchEvent ,然后由 dispatchTouchEvent 方法进行分发,如果dispatchTouchEvent返回true ,则交给这个view的onTouchEvent处理,如果dispatchTouchEvent返回
false ,则交给这个 view 的 interceptTouchEvent 方法来决定是否要拦截这个事件,如果 interceptTouchEvent 返回 true ,也就是拦截掉了,则交给它的 onTouchEvent 来处理,如果 interceptTouchEvent 返回 false ,那么就传递给子 view ,由子 view 的 dispatchTouchEvent 再来开始这个事件的分发。如果事件传递到某一层的子 view 的 onTouchEvent 上了,这个方法返回了 false
,那么这个事件会从这个 view 往上传递,都是 onTouchEvent 来接收。而如果传递到最上面的 onTouchEvent 也返回 false 的话,这个事件就会“消失”,而且接收不到下一次事件。
让子先处理的方法是 从写父的onInterceptTouchEvent事件并返回false
public boolean onInterceptTouchEvent(MotionEvent ev) {
return false;
}
>
1、基础知识
(1) 所有Touch事件都被封装成了MotionEvent对象,包括Touch的位置、时间、历史记录以及第几个手指(多指触摸)等。
(2) 事件类型分为ACTION_DOWN, ACTION_UP, ACTION_MOVE, ACTION_POINTER_DOWN, ACTION_POINTER_UP, ACTION_CANCEL,每个事件都是以ACTION_DOWN开始ACTION_UP结束。
(3) 对事件的处理包括三类,分别为传递——dispatchTouchEvent()函数、拦截——onInterceptTouchEvent()函数、消费——onTouchEvent()函数和OnTouchListener
2、传递流程
(1) 事件从Activity.dispatchTouchEvent()开始传递,只要没有被停止或拦截,从最上层的View(ViewGroup)开始一直往下(子View)传递。子View可以通过onTouchEvent()对事件进行处理。
(2) 事件由父View(ViewGroup)传递给子View,ViewGroup可以通过onInterceptTouchEvent()对事件做拦截,停止其往下传递。
(3) 如果事件从上往下传递过程中一直没有被停止,且最底层子View没有消费事件,事件会反向往上传递,这时父View(ViewGroup)可以进行消费,如果还是没有被消费的话,最后会到Activity的onTouchEvent()函数。
(4) 如果View没有对ACTION_DOWN进行消费,之后的其他事件不会传递过来。
(5) OnTouchListener优先于onTouchEvent()对事件进行消费。
上面的消费即表示相应函数返回值为true。
> Android 中与 Touch 事件相关的方法包括:dispatchTouchEvent(MotionEvent ev)、onInterceptTouchEvent(MotionEvent ev)、onTouchEvent(MotionEvent
ev);能够响应这些方法的控件包括:ViewGroup、View、Activity。方法与控件的对应关系如下表所示:
Touch 事件相关方法 | 方法功能 | ViewGroup | View | Activity |
public boolean dispatchTouchEvent(MotionEvent ev) | 事件分发 | Yes | Yes | Yes |
public boolean onInterceptTouchEvent(MotionEvent ev) | 事件拦截 | Yes | Yes | No |
public boolean onTouchEvent(MotionEvent ev) | 事件响应 | Yes | Yes | Yes |
相关文章推荐
- 查看Android应用包名、Activity的几个方法
- Android开发之Intent跳转到系统应用中的拨号界面、联系人界面、短信界面
- [置顶] Android View(二)-View的scrollTo()以及scrollBy()说明
- 三种简单的图片放大方式
- Android_Fundamentals_chs_1-3(自译)
- android布局性能优化
- Android4.4中拒绝发送Intent.ACTION_MEDIA_MOUNTED扫描SD卡的广播 - Geder
- Android PullToRefresh 分析之五、扩展刷新加载样式
- Android开发之DOM解析xml文件的方法
- Android实现全屏显示的方法
- Android5.X (二) : Material Design:对图像的操作!
- MAC地址获取
- android中 利用缩放加载本地大图片
- Android 获取设备唯一标识码
- Android Makefile 文件讲解
- 7.Android之评分条RatingBar和拖动条SeekBar学习
- Android开发之完成登陆界面的数据保存回显操作实例
- Android屏幕适配全攻略(最权威的官方适配指导)
- 【android】TabLayout文字闪烁问题
- 使用AndroidStudio分析和解决ImageLoader引起内存泄露问题