Android ViewPager和ScrollView嵌套滚动问题解决方案
问题描述:
我的嵌套是ViewPager-->ScrollView-->ViewPager.
首先最里面的ViewPager水平滚动时总是会触发最外层的ViewPager滚动,看了网上很多的解决办法基本上是一样的,需要自定义ViewPager。
import android.content.Context; import android.graphics.PointF; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.view.MotionEvent; /** * 自定义ViewPager,解决ViewPagger嵌套使用时不滑动问题。 * Created by Administrator on 2015/4/20. */ public class HorizontalInnerViewPager extends ViewPager { /** 触摸时按下的点 **/ PointF downP = new PointF(); /** 触摸时当前的点 **/ PointF curP = new PointF(); public HorizontalInnerViewPager(Context context, AttributeSet attrs) { super(context, attrs); mGestureDetector = new GestureDetector(context, new XScrollDetector()); } public HorizontalInnerViewPager(Context context) { super(context); mGestureDetector = new GestureDetector(context, new XScrollDetector()); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return super.onInterceptTouchEvent(ev);//default } @Override public boolean onTouchEvent(MotionEvent ev) { //每次进行onTouch事件都记录当前的按下的坐标 curP.x = ev.getX(); curP.y = ev.getY(); if(ev.getAction() == MotionEvent.ACTION_DOWN){ //记录按下时候的坐标 //切记不可用 downP = curP ,这样在改变curP的时候,downP也会改变 downP.x = ev.getX(); downP.y = ev.getY(); //此句代码是为了通知他的父ViewPager现在进行的是本控件的操作,不要对我的操作进行干扰 getParent().requestDisallowInterceptTouchEvent(true); } if(ev.getAction() == MotionEvent.ACTION_MOVE){ //此句代码是为了通知他的父ViewPager现在进行的是本控件的操作,不要对我的操作进行干扰 getParent().requestDisallowInterceptTouchEvent(true); } return super.onTouchEvent(ev); } }
3.解决了上面的问题,又出现了新的问题,当最里面的ViewPager垂直滚动时外层的ScrollView并不会滚动,解决方法如下:
import android.content.Context; import android.graphics.PointF; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.MotionEvent; /** * 自定义ViewPager,解决ViewPagger嵌套使用时不滑动问题。 * Created by Administrator on 2015/4/20. */ public class HorizontalInnerViewPager extends ViewPager { /** 触摸时按下的点 **/ PointF downP = new PointF(); /** 触摸时当前的点 **/ PointF curP = new PointF(); /** 自定义手势**/ private GestureDetector mGestureDetector; public HorizontalInnerViewPager(Context context, AttributeSet attrs) { super(context, attrs); mGestureDetector = new GestureDetector(context, new XScrollDetector()); } public HorizontalInnerViewPager(Context context) { super(context); mGestureDetector = new GestureDetector(context, new XScrollDetector()); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return super.onInterceptTouchEvent(ev);//default //当拦截触摸事件到达此位置的时候,返回true, //说明将onTouch拦截在此控件,进而执行此控件的onTouchEvent // return true; //接近水平滑动时子控件处理该事件,否则交给父控件处理 // return mGestureDetector.onTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent ev) { //每次进行onTouch事件都记录当前的按下的坐标 curP.x = ev.getX(); curP.y = ev.getY(); if(ev.getAction() == MotionEvent.ACTION_DOWN){ //记录按下时候的坐标 //切记不可用 downP = curP ,这样在改变curP的时候,downP也会改变 downP.x = ev.getX(); downP.y = ev.getY(); //此句代码是为了通知他的父ViewPager现在进行的是本控件的操作,不要对我的操作进行干扰 getParent().requestDisallowInterceptTouchEvent(true); } if(ev.getAction() == MotionEvent.ACTION_MOVE){ float distanceX = curP.x - downP.x; float distanceY = curP.y - downP.y; //接近水平滑动,ViewPager控件捕获手势,水平滚动 if(Math.abs(distanceX) > Math.abs(distanceY)){ //此句代码是为了通知他的父ViewPager现在进行的是本控件的操作,不要对我的操作进行干扰 getParent().requestDisallowInterceptTouchEvent(true); }else{ //接近垂直滑动,交给父控件处理 getParent().requestDisallowInterceptTouchEvent(false); } } return super.onTouchEvent(ev); } private class XScrollDetector extends GestureDetector.SimpleOnGestureListener{ @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // return super.onScroll(e1, e2, distanceX, distanceY); //接近水平滑动时子控件处理该事件,否则交给父控件处理 return (Math.abs(distanceX) > Math.abs(distanceY)); } } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。