onInterceptTouchEvent(MotionEvent)与OnTouchEvent方法分析

来源:互联网 发布:linux rm删除指定文件 编辑:程序博客网 时间:2024/06/05 06:49

先来看官方api对onInerceptTouchEvent的解释:

Implement this method to intercept all touch screen motion events. This allows you to watch events as they are dispatched to your children, and take ownership of the current gesture at any point.Using this function takes some care, as it has a fairly complicated interaction with View.onTouchEvent(MotionEvent), and using it requires implementing that method as well as this one in the correct way. Events will be received in the following order:    You will receive the down event here.    The down event will be handled either by a child of this view group, or given to your own onTouchEvent() method to handle; this means you should implement onTouchEvent() to return true, so you will continue to see the rest of the gesture (instead of looking for a parent view to handle it). Also, by returning true from onTouchEvent(), you will not receive any following events in onInterceptTouchEvent() and all touch processing must happen in onTouchEvent() like normal.    For as long as you return false from this function, each following event (up to and including the final up) will be delivered first here and then to the target's onTouchEvent().    If you return true from here, you will not receive any following events: the target view will receive the same event but with the action ACTION_CANCEL, and all further events will be delivered to your onTouchEvent() method and no longer appear here. Parametersev The motion event being dispatched down the hierarchy.Returns    Return true to steal motion events from the children and have them dispatched to this ViewGroup through onTouchEvent(). The current target will receive an ACTION_CANCEL event, and no further messages will be delivered here. 

实现这个方法拦截所有的屏幕触摸事件,这使你能够在任何时候分发事件给子视图或者选择自身进行处理。

使用这个方法需要注意它与View.onTouchEvent(MotionEvent)的交互相当复杂,与View.onTouchEvent(MotionEvent)交互要求你用正确的方式实现View.onTouchEvent(MotionEvent)并且用正确的方式实现onInterceptTouchEvent(MotionEvent)方法,事件的接收顺序如下:

   ① 首先在onInterceptTouchEvent方法里接收Down事件

   ②Down事件要么被这个视图的子视图处理,要么传给自己的onTouchEvent()方法处理。这意味着你应该实现onTouchEvent()方法并返回ture,然后你将能够看到手势事件的其他事件(手势事件包括Down,move,up)而不是传给他的父视图处理,并且在ViewGroup里的onTouchEvent()中Down事件中返回ture时,在onInterceptTouchEvent()中不会接收触摸事件的其他事件(注意,只有ViewGroup才有onInterceptTouchEvent方法),并且每次触摸事件的其他事件一定会按照正常的顺序由onTouchEvent()处理。

    ③一旦你从onInterceptTouchEvent方法返回false,手势事件中的其他事件(包括抬起手势)将会被先传给onInterceptTouchEvent方法,然后再传递给目标视图的onTouchEvent方法。

    ④如果你从onInterceptTouchEvent方法返回true,你将接收不到任何手势事件的其他事件:目标视图将接收到Action_cancel事件,并且之后的手势事件将会直接被传递给你自身的onTouchEvent方法。而不经过onInterceptTouchEvent方法。

不知道你读懂了没有,我按照的思路再捋一捋,你也可以印证自己的思路。最好的方式是你自己写一个嵌套的布局,然后通过更改onIntercepTouchEvent()方法的返回值,看看他的上级视图,和下级视图是怎么处理的,一定要亲自动手试一试,这个真的是一个值得深究的地方,包括他的设计思想(以后各种炫酷的组合UI效果,都要从这里开始!)

      我们看到的视图一般都是嵌套的视图,里面有很多个视图,视图里面还有子视图,这些视图都是从一个根视图开始的(大家都知道)。当我们触摸屏幕时,系统就会生成触摸事件(MotionEvent),一次触摸事件的定义为:手指按下(Down),滑动(Move),最后抬起(Up)。但是系统不知道你要按下哪个视图,所以先从Down开始传到根视图的

onInterceptTouchEvent()方法,根视图会从自身开始,按照视图的布局层次,依此向下传递,当返回ture时,会调用自身的onTouchEvent()方法,或者即使返回false,但是这个视图已经没有子视图时,只能由自身进行处理,现在我们来说第一种情况:

①返回ture时,从当前视图开始拦截本次触摸事件,本次触摸事件的剩余事件不在向下传递,触摸事件直接交给当前视图的onTouchEvent()方法处理,如果Down事件(记住,现在为止我们还是在说Down事件)在onTouchEvent()方法中返回false,则本次触摸事件的剩余事件都不在传递给当前视图的onInterceptTouchEvent和onTouchEvent方法,而是向上传递给父视图的onTouchEvent,直到有某个上层视图处理了Down事件,然后本次触摸事件的剩余事件会从顶层视图的onIntceptTouchEvnet向下层视图传递,直到传递给处理了本次Down事件的视图。如果一直遍历到根视图都没有onTouchEvent在Down事件中返回true,则,本次触摸事件结束。

②返回false是,Down事件继续向下层视图传递,如果当前视图没有子视图,或者当前视图是一个VIew视图而不是ViewGroup视图时,则交给自身的onTouchEvent()方法处理,如果在Down事件中返回了false,则本次触摸事件的剩余事件都不在传递给当前视图的onInterceptTouchEvent和onTouchEvent方法,而是向上传递给父视图的onTouchEvent,直到有某个上层视图处理了Down事件,然后本次触摸事件的剩余事件会从顶层视图的onIntceptTouchEvnet向下层视图传递,直到传递给处理了本次Down事件的视图。如果一直遍历到根视图都没有onTouchEvent在Down事件中返回true,则,本次触摸事件结束。

0 0
原创粉丝点击