android view手势冲突的通用解决方法

   android手势事件的冲突跟点击事件的分发过程息息相关,由三个重要的方法来共同完成,分别是:dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent。

    public boolean dispatchTouchEvent(MotionEvent ev)

    这个方法用来进行事件的分发。如果事件传递到view,那么这个方法一定会被调用,返回结果受当前View的onTouchEvent和下级View的dispatchTouchEvent方法的影响,表示是否消耗当前事件。

    public boolean onInterceptTouchEvent(MotionEvent event)

   在上述方法内部调用,用来判断是拦截某个事件,如果当前View拦截了某个事件,那么在同一个事件序列当中,此方法不会被再次调用,返回结果表示是否拦截当前事件。

    public boolean onTouchEvent(MotionEvent event)

   在dispathcTouchEvent方法中调用,用来处理点击事件,返回结果表示是否消耗当前事件,如果不消耗,则在同一个事件序列中,当前View无法再次接到事件。

例:

    public boolean dispatchTouchEvent(MotionEvent ev){

             boolean consume = false;

            if(onInterceptTouchEvent(ev)){

                   consume = onTouchEvent(ev);

             }   else {

                 consum = child.dispathcTouchEvent(ev);

           }

        return consume;

     }

   手势冲突的解决方法就是用上面的三个方法;主要分为两种解决方法:·1外部拦截法 2内部拦截法

    1.  外部拦截法

     外部拦截法是指点击事件都先经过父容器的拦截处理,如查父容器需要此事件就拦截,如果不需要此事件就不拦截,这样就可以解决滑动冲突的问题,这种方法比较符合点击事件的分发机制。外部拦截法需要重写父容器的onInterceptTouchEvent方法在内部做相应的拦截即可,例:

public boolean onInterceptTouchEvent(MotionEvent ev) {
   boolean intercepted = false;
   int x = (int) ev.getX();
   int y = (int) ev.getY();
   switch (ev.getAction()){
      case MotionEvent.ACTION_DOWN:
         intercepted = false;
         break;
      case MotionEvent.ACTION_MOVE:
         if(需要拦截){
            intercepted = true;
         }else{
            intercepted = false;
         }
         break;
      case MotionEvent.ACTION_UP:
         intercepted = false;
         break;
      default:
         break;
   }
   return intercepted;
}
  上述代码是外部拦截法的典型逻辑,针对不同的滑动冲突,只需要修改父容器需要拦截这个条件即可,其他均不需做修改。这里对上述代码再描述一下,在onInterceptTouchEvent方法中,首先是ACTION_DOWN这个事件,父容器必须返回false,即不拦截ACTION_DOWN事件,这是因为一旦父容器拦截了ACTION_DOWN,那么后续的ACTION_MOVE和ACTION_UP事件都会直接交由父容器处理,这个时候事件没法再传递给子元素了;其次是ACTION_MOVE事件,这个事件可以根据需要来决定是否拦截,如果父容器需要拦截就返回true,否则返回false;最后是ACTION_UP事件,这里必须返回false,因为ACTION_UP事件本身没有太多意义。
  考虑一种情况,假设事件交由子元素处理,如果父容器在ACTION_UP时返回了true,就会导致子元素无法接收到ACTION_UP事件,这个时候子元素中的onClick事件就无法触发,但是父容器比较特殊,一旦它开始拦截任何一个事件,那么后续的事件都会交给它来处理,而ACTION_UP作为最后一个事件也必定可以传递给父容器,即便父容器的onInterceptTouchEvent方法在ACTION_UP时返回了false。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值