Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 228
Arcos Avatar asked Jul 19 '16 18:07

Arcos


People also ask

How do I turn off swipe in ViewPager Kotlin?

There is no built in way to disable swiping between pages of a ViewPager, what's required is an extension of ViewPager that overrides onTouchEvent and onInterceptTouchEvent to prevent the swiping action. To make it more generalised we can add a method setSwipePagingEnabled to enable/disable swiping between pages.

How do I stop ViewPager from scrolling?

A simple solution is to create your own subclass of ViewPager that has a private boolean flag, isPagingEnabled . Then override the onTouchEvent and onInterceptTouchEvent methods. If isPagingEnabled equals true invoke the super method, otherwise return .

What is PagerAdapter?

PagerAdapter supports data set changes. Data set changes must occur on the main thread and must end with a call to notifyDataSetChanged similar to AdapterView adapters derived from android. widget. BaseAdapter . A data set change may involve pages being added, removed, or changing position.

How do I use the RecyclerView adapter in viewpager2?

Go to the app > java > right click on first package name > new > java class name that class as ViewPager2Adapter. An adapter is an important class to work with Recyclerview. Because it contains all the important methods dealing with RecyclerView. Below is the implementation of the Adapter class.


1 Answers

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) {

        }
    });
like image 159
Shabbir Dhangot Avatar answered Sep 19 '22 04:09

Shabbir Dhangot