浅谈 onInterceptTouchEvent、onTouchEvent与onTouch

from--http://gundumw100.iteye.com/blog/1052270

一、onTouch


onTouch是View中OnTouchListener接口中的方法,处理View及其子类被touch是的事件处理。当然,前提是touch时间能够传递到指定的view。Q1:为什么会传递不到呢?

 
Java代码  收藏代码
  1. /** 
  2.   * Interface definition for a callback to be invoked when a touch event is 
  3.   * dispatched to this view. The callback will be invoked before the touch 
  4.   * event is given to the view. 
  5.   */  
  6.   public interface OnTouchListener {  
  7.       /** 
  8.         * Called when a touch event is dispatched to a view. This allows listeners to 
  9.         * get a chance to respond before the target view. 
  10.         * 
  11.         * @param v The view the touch event has been dispatched to. 
  12.         * @param event The MotionEvent object containing full information about 
  13.         *        the event. 
  14.         * @return True if the listener has consumed the event, false otherwise. 
  15.         */  
  16.        boolean onTouch(View v, MotionEvent event);  
  17.   }  
 /**
   * Interface definition for a callback to be invoked when a touch event is
   * dispatched to this view. The callback will be invoked before the touch
   * event is given to the view.
   */
   public interface OnTouchListener {
       /**
         * Called when a touch event is dispatched to a view. This allows listeners to
         * get a chance to respond before the target view.
         *
         * @param v The view the touch event has been dispatched to.
         * @param event The MotionEvent object containing full information about
         *        the event.
         * @return True if the listener has consumed the event, false otherwise.
         */
        boolean onTouch(View v, MotionEvent event);
   }

二、onTouchEvent

onTouchEvent同样也是在view中定义的一个方法。处理传递到view 的手势事件。手势事件类型包括ACTION_DOWN,ACTION_MOVE,ACTION_UP,ACTION_CANCEL四种事件。

  
Java代码  收藏代码
  1. /** 
  2.     * Implement this method to handle touch screen motion events. 
  3.     * 
  4.     * @param event The motion event. 
  5.     * @return True if the event was handled, false otherwise. 
  6.     */  
  7.    public boolean onTouchEvent(MotionEvent event) {  
  8.     ……  
  9.     ……  
  10.   }  
/**
    * Implement this method to handle touch screen motion events.
    *
    * @param event The motion event.
    * @return True if the event was handled, false otherwise.
    */
   public boolean onTouchEvent(MotionEvent event) {
    ……
    ……
  }

一旦onTouchEvent方法被调用,并返回true则这个手势事件就结束了,并不会向下传递到子控件。Q2:onTouchEvent什么时候被调用呢?

三、onInterceptTouchEvent

onInterceptTouchEvent是在ViewGroup里面定义的。Android中的layout布局类一般都是继承此类的。onInterceptTouchEvent是用于拦截手势事件的,每个手势事件都会先调用onInterceptTouchEvent。

 
Java代码  收藏代码
  1. public boolean onInterceptTouchEvent(MotionEvent ev) {  
  2.           return false;  
  3.   }  
 public boolean onInterceptTouchEvent(MotionEvent ev) {
           return false;
   }

此方法返回false,则手势事件会向子控件传递;返回true,则调用onTouchEvent方法。

onInterceptTouchEvent()用于处理事件并改变事件的传递方向。返回值为false时事件会传递给子控件的onInterceptTouchEvent();返回值为true时事件会传递给当前控件的onTouchEvent(),而不在传递给子控件,这就是所谓的Intercept(截断)。
onTouchEvent() 用于处理事件,返回值决定当前控件是否消费(consume)了这个事件。可能你要问是否消费了又区别吗,反正我已经针对事件编写了处理代码?答案是有区别!比如ACTION_MOVE或者ACTION_UP发生的前提是一定曾经发生了ACTION_DOWN,如果你没有消费ACTION_DOWN,那么系统会认为ACTION_DOWN没有发生过,所以ACTION_MOVE或者ACTION_UP就不能被捕获。

由于onInterceptTouchEvent()的机制比较复杂,上面的说明写的也比较复杂,总结一下,基本的规则是:
1.       down事件首先会传递到onInterceptTouchEvent()方法
2.       如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return false,那么后续的move, up等事件将继续会先传递给该ViewGroup,之后才和down事件一样传递给最终的目标view的onTouchEvent()处理。
3.       如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return true,那么后续的move, up等事件将不再传递给onInterceptTouchEvent(),而是和down事件一样传递给该ViewGroup的onTouchEvent()处理,注意,目标view将接收不到任何事件。
4.       如果最终需要处理事件的view的onTouchEvent()返回了false,那么该事件将被传递至其上一层次的view的onTouchEvent()处理。

5.       如果最终需要处理事件的view 的onTouchEvent()返回了true,那么后续事件将可以继续传递给该view的onTouchEvent()处理。


————————————————————————

更新于 2012-4-16

ritter liu注:网上看见的另外两个讲解版本)

1、如果用户执行一个ACTION_DOWN事件,当前View的onInterceptTouchEvent返回true,则该事件和后续的ACTION_MOVE和,ACTION_UP将不再传递到View的子控件,而是直接交由该View的onTouchEvent来处理。

2、如果上面onInterceptTouchEvent返回false,则该事件和后续的ACTION_UP,ACTION_MOVE将也会透过onInterceptTouchEvent,继而传递到子控件的onInterceptTouchEvent。

3、如果该View的onInterceptTouchEvent返回false,事件传递到目标View,然后目标View的onTouchEvent又返回了false,那么事件将继续传递到目标View的上一级的onTouchEvent。如果目标View的onTouchEvent方法返回了true,说明此事件已被处理了。


如果onInterceptTouchEvent()方法返回为true,则会对Touch事件进行拦截,PageView类的onTouch方法会进行响应从而得到调用。如果返回false,就分两钟情况:(1)我们是点击在它的子控键上进行滑动时,比如我们是点击在桌面的图标上进行左右滑动的,workspace则会把Touch事件分发给它的子控件。(2)而如果仅仅是点击到桌面的空白出Touch事件就不会发生响应。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值