*项目中用到了SwipeRefreshLayout+ViewPager(轮播图)+ScrollView的组合,发现滑动效果很不友好,只有在水平的情况下viewpager才会滑动.影响用户体验.
首先可以确认是滑动冲突产生的影响.
个人因为是Viewpager出现的问题,我重写了ViewPager,当Y轴变化量大于X轴变化量时,对外一个监听,使其关闭其相应的滑动事件.发现时好时坏,有时手指刚刚触碰屏幕,抖动一下就会触发SwipeRefresh或ScrollView的触摸事件.
怀疑这两个的触摸事件比ScrollView的级别高(有兴趣可以查一下源码),那就在这两个空间上做文章,重写这两个控件,发现可行,下面上代码:*
重写SwipeRefreshLayout(出于google):
import android.content.Context;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
/**
* Created by admin on 2017/5/5.
*/
public class MySwipeRefreshLayout extends SwipeRefreshLayout {
private float startY;
private float startX;
// 记录viewPager是否拖拽的标记
private boolean mIsVpDragger;
private final int mTouchSlop;
public MySwipeRefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
@Override
public 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);
}
}
重写ScrollView(出于google):
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ScrollView;
/**
* Created by admin on 2017/5/5.
*/
public class VerticalScrollView extends ScrollView {
private float xDistance, yDistance, lastX, lastY;
public VerticalScrollView(Context context, AttributeSet attrs) {
super(context, 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;
}
return super.onInterceptTouchEvent(ev);
}
}