需求:
RecyclerView中的一个item是viewpager,这样的嵌套,预知会有坑要踩,MD,果不其然,啪啪,两个大饼甩了过来:
(1)viewpager在左右滑动时,再进行上下的手势会触发RecyclerView的上下滚动,解决它;
(2)viewpager在缓慢的左右滑动时,需要一段比较长的距离,需要缩短!(wtf,系统就是这样设计的好吗!?)
public class FixBugViewpager extends ViewPager {
private Context mContext;
public FixBugViewpager(Context context) {
super(context);
this.mContext = context;
fixTouchSlop();
}
public FixBugViewpager(Context context, AttributeSet attrs) {
super(context, attrs);
this.mContext = context;
fixTouchSlop();
}
/**
*这个方法是通过反射,修改viewpager的触发切换的最小滑动速度(还是距离?姑
* 且是速度吧!滑了10dp就给它切换)
**/
private void fixTouchSlop() {
Field field = null;
try {
field = ViewPager.class.getDeclaredField("mMinimumVelocity");
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
field.setAccessible(true);
try {
field.setInt(this, Screen.px2dip(mContext, 10));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
/****
* 滑动距离及坐标 归还父控件焦点
****/
private float xDistance, yDistance, xLast, yLast;
/**
* 是否是左右滑动
**/
private boolean mIsBeingDragged = true;
/**
*重写这个方法纯属是为了告诉Recyclerview,什么时候不要拦截viewpager的滑动
*事件
**/
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
getParent().requestDisallowInterceptTouchEvent(true);
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;
if (!mIsBeingDragged) {
if (yDistance < xDistance * 0.5) {//小于30度都左右滑
mIsBeingDragged = true;
getParent().requestDisallowInterceptTouchEvent(true);
} else {
mIsBeingDragged = false;
getParent().requestDisallowInterceptTouchEvent(false);
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mIsBeingDragged = false;
break;
}
return super.dispatchTouchEvent(ev);
}}