1. 程式人生 > >viewpager和SwipeRefreshLayout下拉重新整理衝突解決

viewpager和SwipeRefreshLayout下拉重新整理衝突解決

重寫SwipeRefreshLayout的onIntercept方法就可以很簡單的解決了。
思路:
1. 因為下拉重新整理,只有縱向滑動的時候才有效,那麼我們就判斷此時是縱向滑動還是橫向滑動就可以了。
2. 縱向滑動就攔截事件,橫向滑動不攔截。
3. 怎麼判斷是縱向滑動還是橫向滑動,只要判斷Y軸的移動距離大於X軸的移動距離那麼就判定為縱向滑動就行了。

以下就是重寫後的SwipeRefreshLayout,直接複製到專案就可以使用了。

/**
* Created by AItsuki on 2016/1/20.
*/
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();
}

@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);
}

}