Вертикальный ViewPager2 с проблемой прокрутки RecyclerView - PullRequest
1 голос
/ 11 марта 2020

Я использую ViewPager2 с двумя фрагментами в вертикальной ориентации. Когда пользователь проводит вниз ко второму фрагменту, появляется RecyclerView, который прокручивает содержимое в том же вертикальном направлении.

Проблема заключается в , что при прокрутке содержимого RecyclerView иногда ViewPager2 ловит события прокрутки, а иногда RecyclerView ловит события прокрутки.

Мне бы хотелось , чтобы при прокрутке пользователя до верхней части RecyclerView ViewPager только проводил назад к первому фрагменту, когда пользователь достиг вершины содержимого в RecyclerView.

Я попытался использовать recyclerView.isNestedScrollingEnabled = false без особой удачи. Я также пытался поместить RecyclerView в NestedScrollView, но это не рекомендуется, потому что RecyclerView затем создает каждый ViewHolder, необходимый для набора данных, и это, очевидно, неэффективно.

Ответы [ 2 ]

2 голосов
/ 11 марта 2020

Итак ... я смог понять это, просто прочитав документацию ?. Я опубликую ответ здесь, чтобы он помог всем остальным, имеющим аналогичную проблему:

Поскольку ViewPager2 не очень хорошо поддерживает вложенные представления прокрутки, в отличие от NestedScrollView, нам нужно обернуть наше вложенное представление прокрутки в пользовательскую оболочку в наш макет, чтобы иметь возможность обрабатывать события касания и пролистывания, которые перехватываются нашим вложенным представлением прокрутки. В нашем случае дочерним элементом будет RecyclerView, а родительским будет ViewPager2.

Вы можете найти класс оболочки здесь . Просто добавьте его в свой проект, а затем оберните в него свой прокручиваемый вид, подобный приведенному ниже:

    <NestedScrollableHost
            android:layout_width="match_parent"
            android:layout_height="match_parent">

        <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/my_recycler_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical" />

    </NestedScrollableHost>

Здесь следует отметить пару вещей: документация говорит, что это решение будет не работает для прокручиваемых представлений, которые находятся в других прокручиваемых представлениях в ViewPager. Это решение работает только для немедленного просмотра прокрутки ViewPager.

Еще одно замечание: класс-оболочка использует requestDisallowInterceptTouchEvent(), чтобы убедиться, что дочернее прокручиваемое представление говорит родителю не выполнять прокрутку, если вместо этого дочернему элементу требуется прокрутка.

0 голосов
/ 19 апреля 2020

Лучшее решение, пока я не получу, - это использовать gestDetector.SimpleOnGestureListener внутри на recyclerView.addOnItemTouchListener (this).

Шаг-1: в методе OnCreate ()

gestureDetector = new GestureDetector(getActivity(), new GestureListener());

Шаг-2 : Реализовать метод addonitemtouchlistenr recyclerView-

recyclerView.addOnItemTouchListener(this);

Шаг 3: Создать класс GestureListener, расширяющий GestureDetector.SimpleOnGestureListener.

public class GestureListener extends GestureDetector.SimpleOnGestureListener {
    private final int Y_BUFFER = 10;

    @Override
    public boolean onDown(MotionEvent e) {
        // Prevent ViewPager from intercepting touch events as soon as a DOWN is detected.
        // If we don't do this the next MOVE event may trigger the ViewPager to switch
        // tabs before this view can intercept the event.
        Log.d("vp", "true1");
        recyclerView.getParent().requestDisallowInterceptTouchEvent(true);
        return super.onDown(e);
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        if (Math.abs(distanceX) > Math.abs(distanceY)) {
            Log.d("vp2", "true");
            // Detected a horizontal scroll, allow the viewpager from switching tabs
            recyclerView.getParent().requestDisallowInterceptTouchEvent(false);
        } else if (Math.abs(distanceY) > Y_BUFFER) {
            // Detected a vertical scroll prevent the viewpager from switching tabs
            Log.d("vp3", "false");
            recyclerView.getParent().requestDisallowInterceptTouchEvent(true);
        }
        return super.onScroll(e1, e2, distanceX, distanceY);
    }
}

Шаг 4: вызвать gestDetector.onTouchEventEvent (e) from) ().

@Override
public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
    gestureDetector.onTouchEvent(e);
    return false;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...