您的位置:首页 > 其它

解决SwipeRefreshLayout嵌套ViewPager产生的滑动冲突的问题

2018-01-26 16:03 344 查看
解决滑动冲突主要有内部解决法和外部解决法,所以对于这个问题可以重写ViewPager的dispatchTouchEvent(MotionEvent ev)方法或者重写SwipeRefreshLayout的onInterceptTouchEvent(MotionEvent ev)根据逻辑判断事件消费给谁。我最先通过内部解决法重写ViewPager 发现没有效果,代码如下:

//重写ViewPager的 dispatchTouchEvent(MotionEvent ev)方法 ,这种方法无法解决!
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {

switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
getParent().requestDisallowInterceptTouchEvent(false);
isMove=false;
lastX=ev.getRawX();
lastY=ev.getRawY();
break;
case MotionEvent.ACTION_MOVE:
float gapX=lastX-ev.getRawX();
float gapY=lastY-ev.getRawY();
if(Math.abs(gapX)>mScaleTouchSlop||Math.abs(gapY)>mScaleTouchSlop){
isMove=true;
}
Logger.i("lx","gapx="+Math.abs(gapX)+"gapy="+Math.abs(gapY)+"isMove="+isMove);
if(Math.abs(gapX)>Math.abs(gapY)){
getParent().requestDisallowInterceptTouchEvent(true);
}else {
getParent().requestDisallowInterceptTouchEvent(false);
}

break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
getParent().requestDisallowInterceptTouchEvent(false);
break;
}
return super.dispatchTouchEvent(ev);
}


困扰了很久,在网上发现是SwipeRefreshLayout重写了requestDisallowInterceptTouchEvent方法导致无效的。

@Override
public void requestDisallowInterceptTouchEvent(boolean b) {
// if this is a List < L or another view that doesn't support nested
// scrolling, ignore this request so that the vertical scroll event
// isn't stolen
if ((android.os.Build.VERSION.SDK_INT < 21 && mTarget instanceof AbsListView)
|| (mTarget != null && !ViewCompat.isNestedScrollingEnabled(mTarget))) {
// Nope.
} else {
super.requestDisallowInterceptTouchEvent(b);
}
}


所以只能用外部解决法喽,解决思路和上面一样,就是当横向滑动的时候不要拦截事件直接给ViewPager去处理,其他情况交事件还是交给SwipeRefreshLayout自己判断处理。代码如下:

public class RefreshLayout extends SwipeRefreshLayout {

private float startY;
private float startX;
// 判断viewPager是否在正在拖拽
private boolean isviewPagerDragger;
private  int mTouchSlop;
public RefreshLayout(Context context) {
super(context);
init(context);
}

public RefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}

private void init(Context context){
//滑动最小距离
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:

startY = ev.getRawY();
startX = ev.getRawX();
// 初始化标记
isviewPagerDragger = false;
break;
case MotionEvent.ACTION_MOVE:
// 如果正在拖拽,直接返回flase,让viewPager处理
if(isviewPagerDragger) {
return false;
}

float gapX = Math.abs(ev.getRawX() - startX);
float gapY = Math.abs(ev.getRawY() - startY);
// 如果是滑动并且是横向滑动,返回flase让viewPager处理
if(gapX > mTouchSlop && gapX > gapY) {
isviewPagerDragger = true;
return false;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// 标记复位
isviewPagerDragger = false;
break;
}
return super.onInterceptTouchEvent(ev);
}

}


嗯,上面就是解决SwipeRefreshLayout嵌套ViewPager产生的滑动冲突的方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: