我不是在问如何处理触摸事件,而是在幕后发生了什么?如果有几个嵌套的小部件,他们看到的事件是什么顺序?开发人员是否可以控制它?理想情况下,我想要一个关于这个主题的文件.
Sur*_*gch 65
我们来看一个视觉示例.
当触摸事件发生时,首先向每个人通知事件,从活动开始并一直到顶部的视图.然后每个人都有机会处理事件,从顶部视图开始,一直回到活动.因此,活动是第一个听到它并且最后有机会处理它.
如果某个ViewGroup想要立即处理触摸事件(并且没有让其他任何人有机会),那么它就可以返回true它onInterceptTouchEvent().活动没有,onInterceptTouchEvent()但您可以覆盖dispatchTouchEvent()以执行相同的操作.
如果View(或ViewGroup)具有OnTouchListener,则触摸事件由处理OnTouchListener.onTouch().否则它由处理onTouchEvent().如果任何触摸事件onTouchEvent()返回true,则处理停止.没有其他人有机会获得它.
上图使事情比实际更简单.例如,在Activity和ViewGroup A(根布局)之间还有Window和DecorView.我把它们排除在上面,因为我们通常不必与它们互动.但是,我会将它们包含在下面.以下描述遵循通过源代码的触摸事件.您可以单击链接以查看实际的源代码.
(更新:源代码已更新,因此行号现已关闭,但单击链接仍会使您找到正确的文件.只需搜索方法名称.)
dispatchTouchEvent()被通知触摸事件.触摸事件作为a传入MotionEvent,其中包含x,y坐标,时间,事件类型和其他信息.superDispatchTouchEvent().Window是一个抽象类.实际的实现是PhoneWindow.superDispatchTouchEvent().DecorView它处理状态栏,导航栏,内容区等.它实际上只是一个FrameLayout子类,它本身就是一个子类ViewGroup.RelativeLayout,a LinearLayout还是a ConstraintLayout,它们都是子类ViewGroup.并且ViewGroup会收到有关触摸事件的通知dispatchTouchEvent().这是上图中的ViewGroup A.ViewGroup会通知任何孩子有触摸事件,包括任何ViewGroup儿童.这是我上图中的ViewGroup B.ViewGroup都可以通过返回来短路通知过程.trueonInterceptTouchEvent()ViewGroup剪切通知短,通知行的自然结束是View dispatchTouchEvent()的调用.OnTouchListener,那么它第一次有机会处理触摸事件onTouch().否则,View onTouchEvent()会处理它.View.虽然,我没有表明这上面的图中,一个ViewGroup是View子类,所以一切我已描述OnTouchListener.onTouch()和onTouchEvent()也适用于ViewGroups.onTouchEvent().我什么时候需要覆盖dispatchTouchEvent()?
如果要在任何视图有机会之前捕获触摸事件,请在活动中覆盖它.对于ViewGroup(包括根视图),然后只需覆盖onInterceptTouchEvent()和onTouchEvent().
我什么时候需要覆盖onInterceptTouchEvent()?
如果您只想窥探即将进入的触摸通知,您可以在此处进行并返回false.
但是,重写此方法的主要目的是让ViewGroup处理特定类型的触摸事件,同时让子处理另一种类型.例如,a ScrollView执行此操作以处理滚动,同时让其子项处理类似Button按钮的操作.相反,如果子视图不想让其父级窃取其触摸事件,则可以调用requestDisallowTouchIntercept().
什么是触摸事件类型?
主要是
ACTION_DOWN - 这是触摸事件的开始.你应该总是返回true的ACTION_DOWN事件onTouchEvent,如果你要处理的触摸事件.否则,您将无法再获得任何活动.ACTION_MOVE - 当您在屏幕上移动手指时,此事件会不断触发.ACTION_UP - 这是触摸事件的最后一个事件.亚军是ACTION_CANCEL.如果树上的ViewGroup决定拦截触摸事件,则会调用此方法.
您可以在此处查看其他类型的MotionEvent .由于Android是多点触控的,因此当其他手指("指针")触摸屏幕时也会触发事件.
Poi*_*ull 24
从活动角度来看:
Touch事件首先传递给Activity.dispatchTouchEvent.这是你可以先抓住它们的地方.
在这里,他们被调度到Window,在那里他们遍历View层次结构,其顺序是最后绘制的Widgets(在其他小部件之上)有机会首先在View.onTouchEvent中处理触摸.如果某些View在onTouchEvent中返回true,则遍历停止并且其他视图不会接收触摸事件.
最后,如果没有View消耗触摸,它将被传递给Activity.onTouchEvent.
这完全是你的控制.而且你所看到的东西在其他东西之上绘制是合乎逻辑的,有机会在它下面绘制的东西之前处理触摸事件.
我已经准备了一个高级图来说明一个简单的流程。
dispatchTouchEvent()- Activity, ViewGroup,ViewonInterceptTouchEvent() —— ViewGrouponTouch()- ViewGroup,View。使用setOnTouchListener()onTouchEvent()- Activity, ViewGroup,View| 归档时间: |
|
| 查看次数: |
10518 次 |
| 最近记录: |