若ViewPager在ScrollView容器里面,则很容易出现体验很差的滑动冲突情况。具体是这样的,当我们在ViewPager上面具有一定角度滑动的时候,系统默认都是当做垂直滑动处理的,即不做任何处理。而外面的ScrollView之后会捕捉这一情况,将屏幕垂直滑动。这不是我们想看到的。
这时,我们可以重写ViewPager,改写它的onTouchEvent函数。具体如下
package com.example.view;
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.GestureDetector.SimpleOnGestureListener;
public class MyViewPager extends ViewPager
{
private float xDistance, yDistance, lastX, lastY;
public MyViewPager(Context co)
{
super(co);
}
public MyViewPager(Context co, AttributeSet attrs)
{
super(co, attrs);
}
/*
@Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
xDistance = yDistance = 0f;
lastX = ev.getX();
lastY = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
final float curX = ev.getX();
final float curY = ev.getY();
xDistance += Math.abs(curX - lastX);
yDistance += Math.abs(curY - lastY);
lastX = curX;
lastY = curY;
if(xDistance > yDistance)
return false;
}
boolean ret = super.onInterceptTouchEvent(ev);
if (ret)
getParent().requestDisallowInterceptTouchEvent(true);
return ret;
}
*/
@Override
public boolean onTouchEvent(MotionEvent ev)
{
boolean ret;
ret = super.onTouchEvent(ev);
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
xDistance = yDistance = 0f;
lastX = ev.getX();
lastY = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
final float curX = ev.getX();
final float curY = ev.getY();
xDistance += Math.abs(curX - lastX);
yDistance += Math.abs(curY - lastY);
lastX = curX;
lastY = curY;
if(xDistance < yDistance)
ret = false;
}
if (ret)
getParent().requestDisallowInterceptTouchEvent(true);
else
getParent().requestDisallowInterceptTouchEvent(false);
return ret;
}
}
红色标记的第一部分代码是处理当有我们滑动时有垂直方向位移时,会做一个判断,若是垂直位移比水平位移大,则认为是垂直滑动,忽略,否则水平滑动。捕捉到。
红色标记的第二部分代码是处理外层的ScrollView的。当时水平滑动时,我们自己处理,告诉ScrollView,让它别碍事了。垂直滑动就让ScrollView处理来处理好了。