重写SwipeRefreshLayout的onIntercept方法就可以很简单的解决了。
思路:
- 因为下拉刷新,只有纵向滑动的时候才有效,那么我们就判断此时是纵向滑动还是横向滑动就可以了。
- 纵向滑动就拦截事件,横向滑动不拦截。
- 怎么判断是纵向滑动还是横向滑动,只要判断Y轴的移动距离大于X轴的移动距离那么就判定为纵向滑动就行了。
以下就是重写后的SwipeRefreshLayout,直接复制到项目就可以使用了。
public class VpSwipeRefreshLayout extends SwipeRefreshLayout {private float startY;private float startX;// 记录viewPager是否拖拽的标记private boolean mIsVpDragger;private final int mTouchSlop;public VpSwipeRefreshLayout(Context context, AttributeSet attrs) {super(context, attrs);mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {int action = ev.getAction();switch (action) {case MotionEvent.ACTION_DOWN:// 记录手指按下的位置startY = ev.getY();startX = ev.getX();// 初始化标记mIsVpDragger = false;break;case MotionEvent.ACTION_MOVE:// 如果viewpager正在拖拽中,那么不拦截它的事件,直接return false;if(mIsVpDragger) {return false;}// 获取当前手指位置float endY = ev.getY();float endX = ev.getX();float distanceX = Math.abs(endX - startX);float distanceY = Math.abs(endY - startY);// 如果X轴位移大于Y轴位移,那么将事件交给viewPager处理。if(distanceX > mTouchSlop && distanceX > distanceY) {mIsVpDragger = true;return false;}break;case MotionEvent.ACTION_UP:case MotionEvent.ACTION_CANCEL:// 初始化标记mIsVpDragger = false;break;}// 如果是Y轴位移大于X轴,事件交给swipeRefreshLayout处理。return super.onInterceptTouchEvent(ev);}
}