防止自定义视图对水平滚动作出反应

时间:2015-01-22 07:39:16

标签: android gesturedetector

我有一个自定义的可滚动视图 - 此视图扩展了View而不是ScrollView / ListView

相反,它有一个简单的OnGestureListener 它在垂直滚动上表现很好 - 现在我将它嵌入到ViewPager中 并且为了滚动viewpager,我需要确保将我的手指放在给定视图之外以便能够在页面之间滚动

如果滚动是水平的,我该怎么做才能防止我的视图接受滚动?

public WheelScroller(Context context, ScrollingListener listener) {
    gestureDetector = new GestureDetector(context, new SimpleOnGestureListener() {
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            // Do scrolling in onTouchEvent() since onScroll() are not call immediately
            //  when user touch and move the wheel
            return true;
        }

        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            lastScrollPosition = 0;
            scrollerFling(lastScrollPosition, (int) velocityX, (int) velocityY);
            setNextMessage(MESSAGE_SCROLL);
            return true;
        }



    });
    gestureDetector.setIsLongpressEnabled(false);

    scroller = new Scroller(context);

    this.listener = listener;
    this.context = context;
}

/**
 * Set the the specified scrolling interpolator
 * @param interpolator the interpolator
 */
public void setInterpolator(Interpolator interpolator) {
    scroller.forceFinished(true);
    scroller = new Scroller(context, interpolator);
}

/**
 * Scroll the wheel
 * @param distance the scrolling distance
 * @param time the scrolling duration
 */
public void scroll(int distance, int time) {
    scroller.forceFinished(true);
    lastScrollPosition = 0;
    scrollerStartScroll(distance, time != 0 ? time : SCROLLING_DURATION);
    setNextMessage(MESSAGE_SCROLL);
    startScrolling();
}

/**
 * Stops scrolling
 */
public void stopScrolling() {
    scroller.forceFinished(true);
}

/**
 * Handles Touch event 
 * @param event the motion event
 * @return
 */
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {

        case MotionEvent.ACTION_DOWN:
            lastTouchedPosition = getMotionEventPosition(event);
            scroller.forceFinished(true);
            clearMessages();
            listener.onTouch();
            break;

        case MotionEvent.ACTION_UP:
            if (scroller.isFinished())
                listener.onTouchUp();
            break;


        case MotionEvent.ACTION_MOVE:
            // perform scrolling
            int distance = (int)(getMotionEventPosition(event) - lastTouchedPosition);
            if (distance != 0) {
                startScrolling();
                listener.onScroll(distance);
                lastTouchedPosition = getMotionEventPosition(event);
            }
            break;
    }

    if (!gestureDetector.onTouchEvent(event) && event.getAction() == MotionEvent.ACTION_UP) {
        justify();
    }

    return true;
}

2 个答案:

答案 0 :(得分:0)

写一个custom ViewPager来处理这样的事件:

public class SelectiveViewPager extends ViewPager {
    private boolean paging = true;

    public SelectiveViewPager(Context context) {
        super(context);
    }

    public SelectiveViewPager(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        if (paging) {
            return super.onInterceptTouchEvent(e);
        }

        return false;
    }

    public void setPaging(boolean p) {
        paging = p;
    }

}

在您的评分视图中,使用此寻呼机实例和setPagging(true or false);关于内部或外部的触摸。这里onInterceptTouchEvent()正在一起讨论触摸事件。

查看此链接以获取更多参考。 onInterceptTouchEvent

答案 1 :(得分:0)

在fling方法中,检查两个运动事件的y值。像这样:

    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

        //You can set the threshhold to an amount you think is enough to detect a horizontal scroll. 
        //This means the difference between the fingers position on the y axis didn't change too much, so it was a horizontal scroll not a vertical one.
        boolean horizontalScroll = Math.abs(e1.getY()-e2.getY())<HORIZONTAL_SCROLL_THRESHHOLD;
        if(!horizontalScroll) {
        lastScrollPosition = 0;
        scrollerFling(lastScrollPosition, (int) velocityX, (int) velocityY);
        setNextMessage(MESSAGE_SCROLL);
        }

        return !horizontalScroll; 
        //If it was horizontal scroll it will return false so the event get's passed behind.
    }