3.5 View的滑动冲突(三)

此篇文章用内部拦截法解决内外View滑动方向不一致的冲突问题

1. 重写ListView如下

public class ListViewEx extends ListView {
    int mLastX,mLastY;

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

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        int x = (int) ev.getX();
        int y = (int) ev.getY();
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                // True if the child does not want the parent to intercept touch events.
                // down时不希望父Veiw拦截,父View拦截后,后续事件无法传到子View中
                getParent().requestDisallowInterceptTouchEvent(true);
                break;
            case MotionEvent.ACTION_MOVE:
                int deltaX = x - mLastX;
                int deltaY = y - mLastY;
                if (Math.abs(deltaX)>Math.abs(deltaY)){
                    // false 子类希望父View拦截(disallowIntercept,不允许拦截,不拦截为true则不拦截,为false则拦截)
                    getParent().requestDisallowInterceptTouchEvent(false);
                }
                break;
            case MotionEvent.ACTION_UP:
                break;
            case MotionEvent.ACTION_CANCEL:
                break;
        }
        mLastX = x;
        mLastY = y;
        return super.dispatchTouchEvent(ev);
    }
}

2. 外部HorizontalScrollViewEx修改拦截方法

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    int x = (int) event.getX();
    int y = (int) event.getY();
    int action = event.getAction();
    if (action == MotionEvent.ACTION_DOWN) {
        mLastX = x;
        mLastY = y;
        if (!mscroller.isFinished()) {
            mscroller.abortAnimation();
            return true;
        }
        return false;
    } else {
        return true;
    }
}

HorizontalScrollViewEx中的onTouchEvent方法是处理它应有的效果的,如左右滚动(move)时,View要左右跟着滚动。松开手指时(up),要根据速度判断,自动滚到下一页或上一页。

3. 外部拦截法和内部拦截法的区别

外部拦截法符合事件的分发流程,简单。内部拦截法尽管也能实现,但稍显复杂,建议使用外部拦截法。

你可能感兴趣的:(3.5 View的滑动冲突(三))