Trinea / android-auto-scroll-view-pager

Android auto scroll viewpager or viewpager in viewpager
http://p.codekk.com/
Apache License 2.0
1.67k stars 670 forks source link

don't consume touch event when scroll up or down #29

Closed hadifar closed 7 years ago

hadifar commented 8 years ago

Hi , first Thanks for your library.

I want to put auto-scroll-view-pager as header of my listview (RecyclerView) but When I scroll up/down it consume touch event. I use following piece of code to handle this issue (I put it in dispatchTouchEvent method ):


    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        int action = MotionEventCompat.getActionMasked(ev);

        if (stopScrollWhenTouch) {
            if ((action == MotionEvent.ACTION_DOWN) && isAutoScroll) {
                isStopByTouch = true;
                stopAutoScroll();
            } else if (ev.getAction() == MotionEvent.ACTION_UP && isStopByTouch) {
                startAutoScroll();
            }
        }

        if (slideBorderMode == SLIDE_BORDER_MODE_TO_PARENT || slideBorderMode == SLIDE_BORDER_MODE_CYCLE) {
            touchX = ev.getX();
            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
                downX = touchX;
            }
            int currentItem = getCurrentItem();
            PagerAdapter adapter = getAdapter();
            int pageCount = adapter == null ? 0 : adapter.getCount();
            /**
             * current index is first one and slide to right or current index is last one and slide to left.<br/>
             * if slide border mode is to parent, then requestDisallowInterceptTouchEvent false.<br/>
             * else scroll to last one when current item is first one, scroll to first one when current item is last
             * one.
             */
            if ((currentItem == 0 && downX <= touchX) || (currentItem == pageCount - 1 && downX >= touchX)) {
                if (slideBorderMode == SLIDE_BORDER_MODE_TO_PARENT) {
                    getParent().requestDisallowInterceptTouchEvent(false);
                } else {
                    if (pageCount > 1) {
                        setCurrentItem(pageCount - currentItem - 1, isBorderAnimation);
                    }
                    getParent().requestDisallowInterceptTouchEvent(true);
                }
                return super.dispatchTouchEvent(ev);
            }
        }
       //----------------this is my code ----------------
        boolean consumeTouch = false;
        if (action == MotionEvent.ACTION_DOWN) {
            touchY = ev.getY();
        } else if (action == MotionEvent.ACTION_UP) {
            consumeTouch = Math.abs(touchY - ev.getY()) > 0;
        }
        if (consumeTouch)
            getParent().requestDisallowInterceptTouchEvent(true);
        else
            getParent().requestDisallowInterceptTouchEvent(false);

        return super.dispatchTouchEvent(ev);
    }

It's work somehow but have issue. When I scroll up/down autoScroll mode not worked. Can you help me to solve this issue ?

youfacepalm commented 8 years ago

Would love a solution to this

youfacepalm commented 8 years ago

After fiddling with the code for a while I was able to fix the issue like the following. This is based on @AmirHadifar 's solution

boolean consumeTouch = false;
if (action == MotionEvent.ACTION_DOWN) {
    touchY = ev.getY();
} else if (action == MotionEvent.ACTION_UP) {
    consumeTouch = Math.abs(touchY - ev.getY()) > 0;
}

if (consumeTouch) {
    getParent().requestDisallowInterceptTouchEvent(true);
} else {
    getParent().requestDisallowInterceptTouchEvent(false);
    if(stopScrollWhenTouch)
        startAutoScroll();
}
amanzan commented 7 years ago

@youfacepalm where exactly goes your code? I have the same issue

edit: after testing, there are also issues with this fix. Swiping is a pain now.

amanzan commented 7 years ago

Replace dispatchTouchEvent method by this:

@Override public boolean dispatchTouchEvent(MotionEvent ev) { int action = MotionEventCompat.getActionMasked(ev); if (stopWhenTouch) { switch (action) { case MotionEvent.ACTION_DOWN: if (isAutoScroll) { isStopedWhenTouch = true; stopAutoScroll(); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_OUTSIDE: if (isStopedWhenTouch) { startAutoScroll(); } break; } } return super.dispatchTouchEvent(ev); }

(sorry for the bad formatting)

Credit to https://github.com/demoNo/AutoScrollViewPager/blob/master/library/src/main/java/com/github/demono/AutoScrollViewPager.java

ashokbg commented 7 years ago

@amanzan suggestion worked ..

`@Override public boolean dispatchTouchEvent(MotionEvent ev) { int action = MotionEventCompat.getActionMasked(ev); if (stopWhenTouch) { switch (action) { case MotionEvent.ACTION_DOWN: if (isAutoScroll) { isStopedWhenTouch = true; stopAutoScroll(); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_OUTSIDE: if (isStopedWhenTouch) { startAutoScroll(); } break; } } return super.dispatchTouchEvent(ev); }