Android解决viewpager,fragment,SwipeRefreshLayout,ScrollView,横向滚动控件后产生横向滚动控件不能滚动或没有边界处理的冲突

急需解决的两大冲突问题:
1.解决最内层嵌套的横向滚动的view不能滚动问题。
2.解决横向滚动控件滑动到边界后,最外层Viewpager滑动跳动的问题。

一、解决最内层嵌套的横向滚动的view不能滚动问题。
1.现在想实现一个功能,就是viewpager嵌套fragment嵌套SwipeRefreshLayout嵌套ScrollView嵌套横向滚动控件后,横向滚动的控件仍然具有边界处理的效果。
尝试过用的是著名的开源mpandroidChart的横向滚动的柱状图,但是在前面的几个控件的嵌套下,横向滚动失灵。网上的解决方案是重写ScrollView的canScroll()方法,如果是滚动的柱状图,那么就就return true。这样是能够滚动,但是柱状图没有了边界处理。即滚动到最左或是最右边的时候,不能触发viewpager的翻页效果。
这里写图片描述
2.由于开源框架和他人自定义的view不能随心控制,因此自定义的了一个横向滚动的柱状图,定义很简单。(可以查看上篇博客:https://blog.csdn.net/yuezheyue123/article/details/81298754) 发现如果在上面几个控件嵌套下,的确会出现不能滚动的bug。后来又发现如果去掉SwipeRefreshlayout后,控件又正常了。因此很可能就是SwipeRefreshLayout在事件的分发拦截的过程中出现问题。
3.查看SwiperefreshLayout的源码,发现它重写了dispatchTouchEvent()方法。因此我猜测很可能就是它的代码有问题。我在这个方法的MotionEvent.ACTION_DOWN中设置getparent().requestDisallowInterceptTouchEvent(true),果真能够正常的滚动。那么我想如果在这里我判断当前是否横向滚动的的控件,并且当柱状图到达边界后,通过设置true或者false来决定viewpager是否进行滑动。
首先想到的方法就是遍历当前下面的所有的view,并且判断是否是柱状图。
并且在柱状图中添加方法,isMove()–用来获取当前的柱状图滑动状态,目的是判断当前滑动的是哪个view。
isBoundary()–用来获取当前的柱状图是否到达边界,
这样就确定了当前操作的视图了。使用break跳出循环。
这里写图片描述
这里写图片描述

二、解决横向滚动控件滑动到边界后,最外层Viewpager滑动跳动的问题。
1.本来以为上面的的操作已经万事大吉,结果在快速滑动横向柱状图的时候,发现viewpager突然跳动。我本能的就感觉是在viewpager的onTouchEvent()中出现了问题。但这样一下子就陷入了误区,但是也提供了一种思路。我首先打印了viewpager中onTouchEvent()方法中的action,结果发现仅仅是响应了action_move 和action_up
这里写图片描述
2.那么我看了源代码后,发现肯定是在因为在viewpager中没有响应action_down的缘故,导致在计算距离的时候发生偏移。请看源代码:
这里写图片描述
因此解决方案就是我要重新进行赋值,校准这些数值,但是第一个困难就是父类的方法和属性都是私有的,必须使用反射才能获取到数值,那么就开了第一次错误的尝试:
这里写图片描述
我在自定义的viewpager中重写了action_down的所有方法,然后去尝试,竟然发现没有效果,我原本以为是反射错误(但的确当时有些写错了),但是经过修正后,仍然没有效果,我打印了修改前后的各个数值,发现最多相差不够100px,在屏幕上也还没有一个手指宽。一般才相差10-20px,这些基本就是忽略不计了。但是我拼命的以为这个思路是正确,但是为什么没有效果,折腾了很久也是没有效果。
3.下班回家路上,我突然想到是不是其他的方法出现了问题,比如onInterceptTouchEvent()和dispatchTouchEvent()?回到家一看源码,果真是日了。在onInterceptTouchEvent()中基本和onTouchEvent()中类似,看源码:
这里写图片描述
打印action后,发现仅仅响应action_move和action_down,因此修改代码:
这里写图片描述
最后完美解决问题,详细看下面源码。
源代码
https://github.com/yunzheyue/honrizontalBar

猜你喜欢

转载自blog.csdn.net/yuezheyue123/article/details/81298884