需求:
RecyclerView中的一個item是viewpager张吉,這樣的嵌套仲翎,預(yù)知會有坑要踩甘磨,MD,果不其然患整,啪啪拜效,兩個大餅甩了過來:
(1)viewpager在左右滑動時,再進行上下的手勢會觸發(fā)RecyclerView的上下滾動各谚,解決它紧憾;
(2)viewpager在緩慢的左右滑動時,需要一段比較長的距離嘲碧,需要縮短5纠(wtf,系統(tǒng)就是這樣設(shè)計的好嗎!望抽?)
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的觸發(fā)切換的最小滑動速度(還是距離?姑
* 且是速度吧煤篙!滑了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);
}}