最近自己在练手一个漫画阅读的项目,为了更好的翻页体验,所以用到了开源的VerticalViewPager去向下切换漫画页面,由于漫画是长图,所以要用到ScrollView去滑动.
这时问题来了,当我在滑动ScrollView到底部时,发现VerticalViewPager不能向下翻页了,尝试了多次才可以翻页,这时猛然想到是嵌套进去的ScrollView将向下滑动的事件给消费掉了,原因知道了,那就要重写ScrollView的触摸事件啦.
要分两种情况去分析:
1.当ScrollView滑动到顶部时,我就要放弃处理触摸事件,让VerticalViewPager去向上翻页
2.当ScrollView滑动到底部时,我也要放弃处理触摸事件,让VerticalViewPager去向下翻页
这时就需要知道什么时候ScrollView滑动到了顶部.什么时候ScrollView滑动到了底部
顶部的情况很简单,当getScrollY()==0时就说明了在顶部,进行false就行了
底部的话就需要去判断ScrollView的最大滑动距离加上ScrollView本身的高度有没有超过孩子imageview的高度
超过了的话,也进行false
ScrollView的最大滑动距离:就是滑动到底部时的getScrollY()值
ScrollView本身的高度:可以就当它是手机屏幕的高度
imageview的高度:相当于就是装在ScrollView里图片的高度,也就是ScrollView撑满了后的最大
/**
* User: xiemiao
* Date: 2016-10-19
* Time: 21:13
* Desc: 垂直viewpager和scrollview的滚动冲突解决
*/
public class MyScrollView extends ScrollView {
public MyScrollView(Context context) {
super(context);
}
public MyScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private int downY = 0;//初始化按下时Y坐标变量
@Override
public boolean onTouchEvent(MotionEvent ev) {
View childView = getChildAt(0);//获取孩子控件
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
//记录按下时的y坐标(用来判断是向下还是向上滑动的操作)
downY = (int) ev.getY();
break;
case MotionEvent.ACTION_MOVE:
//判断向上滑动的情况,滑动到底部
// 当朝着Y方向滑动到底部的坐标(即scrollview的最大滑动量)+scrollview本身的高度大于或等于了孩子控件的高度
//说明这时要进行页面切换了,scrollview就返回false,不去进行触摸操作,给viewpager去向下翻页
if (downY > ev.getY() && childView != null && getScrollY() + getMeasuredHeight()
>= childView.getMeasuredHeight()) {
return false;
}
//判断向下滑动的情况,到顶部
//如果朝着Y方向滑动的坐标是小于等于0,说明是向上翻页的趋势,这时也返回false,给viewpager去翻页
if (downY < ev.getY() && getScrollY() <= 0) {
return false;
}
break;
}
return super.onTouchEvent(ev);
}
}