ScrollView和ViewPager滑动冲突的解决和整理

       最近看了看以前的bug和解决方法,发现自己在解决问题后很少去总结,现在发现下次再遇到的时候还是需要去查阅,在这里我还是把它拿出来总结了一下。当时在做项目的时候,是在ViewPager里面嵌套了ScrollView,导致了滑动十分的卡顿的bug,最后通过了ScrollView的onInterceptTouchEvent的重写,解决了这个bug。重写了ScrollView的onInterceptTouchEvent的代码:

    private float mDownPosX = 0;  
    private float mDownPosY = 0;
	@Override  
    public boolean onInterceptTouchEvent(MotionEvent ev) {  
        final float x = ev.getX();  
        final float y = ev.getY();  
          
        final int action = ev.getAction();  
        switch (action) {  
        case MotionEvent.ACTION_DOWN:  
            mDownPosX = x;  
            mDownPosY = y;  
              
            break;  
        case MotionEvent.ACTION_MOVE:  
            final float deltaX = Math.abs(x - mDownPosX);  
            final float deltaY = Math.abs(y - mDownPosY);  
            if (deltaX > deltaY) {  
                return false;  
            }  
        }  
                  
        return super.onInterceptTouchEvent(ev);  
    }
     首先记录了按下的坐标,然后根据计算x和y轴的移动距离大小来控制滑动时间,如果X轴移动的距离大于y轴的距离, 则返回false,不在执行ScrollView的onTouchEvent方法,也就拦截了ScrollView的上下滑动事件,奖滑动事件交给了ViewPager去处理。说到这里我就总结一下onInterceptTouchEvent和onTouchEvent方法吧。

一、onTouchEvent:

        onTouchEvent是在view中定义的一个方法。处理传递到view 的手势事件。手势事件类型包括ACTION_DOWN,ACTION_MOVE,ACTION_UP,ACTION_CANCEL四种事件。一旦onTouchEvent方法被调用,并返回true则这个手势事件就结束了,并不会向下传递到子控件。

二、onInterceptTouchEvent:

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

      onInterceptTouchEvent()用于处理事件并改变事件的传递方向。返回值为false时事件会传递给子控件的onInterceptTouchEvent();返回值为true时事件会传递给当前控件的onTouchEvent(),而不在传递给子控件。由于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()处理。


下面在分析一下事件分发的机制,分发机制是由上往下的。有这样一个方法dispatchTouchEvent,该方法用来进行事件的分发,即无论ViewGroup或者View的事件,都是从这个方法开始的。然后就会执行上面的操作,直到这个事件被消耗。通过源代码的分析,大体是这样的:如果一个事件传递到了ViewGroup处,首先会判断当前ViewGroup是否要拦截事件,即调用onInterceptTouchEvent()方法;如果返回true,则表示ViewGroup拦截事件,那么ViewGroup就会调用自身的onTouchEvent来处理事件;如果返回false,表示ViewGroup不拦截事件,此时事件会分发到它的子View处,即调用子View的dispatchTouchEvent方法,如此反复直到事件被消耗掉。



  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值