问题:通常在滑动横向的控件时如viewpager或者横向的listview亦或是最新的recycleview,都会产生稍微滑动的有偏差,会导致 scrollview的上下滑动,体验特别不佳
处理:在滑动的时候假如scrollview的上下收到了触发,则返回到子布局中去,故重写scrollview如下:
public class ScrollView1 extends ScrollView{ private boolean canScroll; private GestureDetector mGestureDetector; View.OnTouchListener mGestureListener; public ScrollView1(Context context, AttributeSet attrs) { super(context, attrs); mGestureDetector = new GestureDetector(new YScrollDetector()); canScroll = true; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if(ev.getAction() == MotionEvent.ACTION_UP) canScroll = true; return super.onInterceptTouchEvent(ev) && mGestureDetector.onTouchEvent(ev); } class YScrollDetector extends GestureDetector.SimpleOnGestureListener { @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { if(canScroll) if (Math.abs(distanceY) >= Math.abs(distanceX)) canScroll = true; else canScroll = false; return canScroll; } }
后来多次测试,发现有问题,上下有的时候划不动了,故改成如下:
public class ScrollView1 extends ScrollView{ private float xDistance, yDistance, xLast, yLast; public ScrollView1(Context context) { super(context); } public ScrollView1(Context context, AttributeSet attrs) { super(context, attrs); } public ScrollView1(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: xDistance = yDistance = 0f; xLast = ev.getX(); yLast = ev.getY(); break; case MotionEvent.ACTION_MOVE: final float curX = ev.getX(); final float curY = ev.getY(); xDistance += Math.abs(curX - xLast); yDistance += Math.abs(curY - yLast); xLast = curX; yLast = curY; /** * X轴滑动距离大于Y轴滑动距离,也就是用户横向滑动时,返回false,ScrollView不处理这次事件, * 让子控件中的TouchEvent去处理,所以横向滑动的事件交由ViewPager处理, * ScrollView只处理纵向滑动事件 */ if (xDistance > yDistance) { return false; } } return super.onInterceptTouchEvent(ev); } }