[原创]本地解决ViewPager和Webview引起的滑动冲突问题

BAT 批处理程序 2017-09-15

前言:毕业之后在高薪的后厂村互联网公司和生活工作平衡的体制内之间纠结了好久,最后选择了后者,毕竟后厂村只要有技术什么时候都能去,体制内基本上除了应届生这次机会基本上就再也进不去了,社招就算进去也没有编制。基于“面对两难选择时,选择没有体验过的那个”的原则,选择了体制,然后有幸被分配到了移动端开发的部门,以前积累的一点小知识算是没有浪费。负责的这个app每天有几千人用,虽然大家都在吐槽它速度慢,体验差,bug多,适配不友好……但是如果你是他的客户,你是不得不用的,因为……他管钱。

需求:体制内的程序还是以稳定为主,所以技术探索并不像后厂村的大厂一样经常探索。现在一个需求就是解决ViewPager和webview轮播图的滑动问题。看了一些博客我认为由js端传给android端轮播图的位置的解决方案体验最好。但是由于种种原因,上级希望能够android端本地解决。本地解决问题就来了,我怎么知道webview里面的轮播图在哪里?在我目前的知识储备来看,单凭android端是做不到的。

解决方法:所以就想了一个本地的笨方法,把屏幕分割成左中右三份,从手指落地的位置开始算,在两边滑动就滑动ViewPager,在中间滑动就滑动webview轮播图片。

两个思路:一个是给webview添加onTouchListener,使用requestDisallowInterceptTouchEvent()方法告诉ViewPager要不要拦截。太简单,会出现拦截不及时,轮播图还会滑动一点,造成轮播图卡住,不自动轮播,需要手动调整复位才能继续轮播。我认为是js端的问题,但是无法解决。为什么?如果能解决早就可以js端告诉android端轮播图在哪了!

第二个思路就是重写ViewPager的OnInterceptTouchEvent()方法,根据不同的情况对情况进行拦截。

第一步:ACTION_DOWN在两边OnInterceptTouchEvent()返回true,在中间返回false。嗯,这样不会发生轮播图滑动一点的情况了。可是,在两边的都拦截了,那在Fragment里面两边的控件 怎么办,没法点击了,被拦截了。

第二步:所以即使在两边也有不被拦截的情况。目前发现两种,一种是点击,一种是上下滑动。因为一个触摸事件是先一个ACTION_DOWN,后面若干个ACTION_MOVE,最后一个ACTION_UP。这个move只要手指在屏幕上就会一直调用,所以哪怕是点击事件有时也会出现move。因为滑动时间和距离是一直增加的,所以就在move滑动时间和距离大于某个数之后return。经过调试和体验,基本上达到了要求。

无法解决的问题:

如果一个fragment包含多个webview或其他控件,一个webview只包括一个html控件还好。如果一个fragment包含只包含一个大webview,大webview里是一个完整的网页,甚至没有轮播图,那就造成即使在中间滑动也没什么用。这个问题只靠android端我现在还没好的方案,哪个大神有可以赐教。

下面贴出OnIntercepTouchEvent代码

@Override
    public boolean onInterceptTouchEvent(MotionEvent event){
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX=event.getX();
                downY=event.getY();
                downTime= System.currentTimeMillis();
                if (downX< ScreenUtil.getScreenWidthPixels(getContext())/5||downX>ScreenUtil.getScreenWidthPixels(getContext())/5*4){
                    isIntercept=true;
                }else {
                    isIntercept=false;
                    return false;
                }
                break;
            case MotionEvent.ACTION_UP:
                break;
            case MotionEvent.ACTION_MOVE:
                long moveTime= System.currentTimeMillis();
                float moveX=event.getX();
                float moveY=event.getY();
                if (isIntercept&&(Math.abs(moveY-downY)<20)&&((moveTime-downTime>300)||(Math.abs(moveX-downX)>9))){
                    return true;
                }
                if (isIntercept&&(Math.abs(moveY-downY)>=20)){
                    return false;
                }
                break;
        }
        return super.onInterceptTouchEvent(event);
    }

相关推荐