Search code examples
androidandroid-fragmentsandroid-viewpagerandroid-recyclerview

Disable ViewPager paging when child recyclerview scrolls to last item


I have a viewpager and within one of the fragments I have two separate fragments containing a vertical and a horizontal recyclerview respectively.

When I scroll the horizontal recyclerview to the last item and try to swipe further, the viewpager scrolls to the next page. I do not want this to happen. I want to disable the viewpager's paging when I try to overscroll the horizontal recyclerview.

However, I do not want to disable the viewpager's paging when I swipe anywhere else. For example, If I were to swipe on the vertical recyclerview or any empty space within the parent fragment, it should still cause the viewpager to change pages.

I read in this SO question, how to disable paging of the viewpager. Also this SO question is similar in that there is a child viewpager, however I have not had success trying to replicate that with a horizontal recyclerview.

Here's some structure:

The custom viewpager which allows me to disable paging(took it from first SO link above):

public class CustomViewPager extends ViewPager {

private boolean enabled;

public CustomViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.enabled = true;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (this.enabled) {
        return super.onTouchEvent(event);
    }

    return false;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    if (this.enabled) {
        return super.onInterceptTouchEvent(event);
    }

    return false;
}

public void setPagingEnabled(boolean enabled) {
    this.enabled = enabled;
} }

For the horizontal recyclerview I set an ontouchlistener(similar to second SO link above):

horizontalRecyclerView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    switch(event.getAction()){
                        case MotionEvent.ACTION_MOVE:
                            customViewPager.setPagingEnabled(false);
                            break;
                        case MotionEvent.ACTION_UP:
                            customViewPager.setPagingEnabled(true);
                            break;
                    }
                    return false;
                }
            });

Extra observations: I noticed that sometimes if I long press the horizontal recyclerview before I swipe it will not go to the next page of the viewpager. However, if I swipe quickly the viewpager will go to the next page.

Does anyone know the proper way to do this?

Any help is appreciated.


Solution

  • Here is solution.

    requestDisallowInterceptTouchEvent()
    

    This method will not allow parent to move. It stops viewpager touch event.

    horizontalRecyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
            @Override
            public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
                int action = e.getAction();
                switch (action) {
                    case MotionEvent.ACTION_MOVE:
                        rv.getParent().requestDisallowInterceptTouchEvent(true);
                        break;
                }
                return false;
            }
    
            @Override
            public void onTouchEvent(RecyclerView rv, MotionEvent e) {
    
            }
    
            @Override
            public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
    
            }
        });