RecyclerView ScrollListener внутри NestedScrollView

У меня EndlessRecyclerView в конце NestedScrollView. EndlessRecyclerView означает: когда пользователь прокручивает до конца recyclerView, он загружает больше данных. Это уже реализовано и работает где-то еще, но когда я помещаю recyclerView внутрь NestedScrollView, события OnScrollListener не срабатывают.

XML-дизайн:

<NestedScrollView>

     <Other views/>

     <EndlessRecyclerView/>

</NestedScrollView >

Код:

recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            // This is never fired! Here is where I implement the logic of EndlessRecyclerView
        }
    });

Как мне получить событие прокрутки для вышеуказанного случая?

Я знаю, что иметь два прокручиваемых представления друг в друге - это нехорошо. Но как мне получить вышеуказанный случай без двух прокручиваемых представлений?

Я уже переходил по этой ссылке, но она не работает: событие прокрутки для recyclerview внутри scrollview android




Ответы (2)


Чтобы добиться бесконечной прокрутки для представления ресайклера, которое находится в NestedScrollView, вы можете использовать «NestedScrollView.OnScrollChangeListener»

nestedScrollView.setOnScrollChangeListener((NestedScrollView.OnScrollChangeListener) (v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
            if(v.getChildAt(v.getChildCount() - 1) != null) {
                if ((scrollY >= (v.getChildAt(v.getChildCount() - 1).getMeasuredHeight() - v.getMeasuredHeight())) &&
                        scrollY > oldScrollY) {
                        //code to fetch more data for endless scrolling
                }
            }
        });

Здесь v.getChildCount() -1 должно дать вам представление ресайклера, для которого вы реализуете бесконечную прокрутку.

Также scrollY > oldScrollY подтверждает, что страница прокручивается вниз.

Ссылка: NestedScrollView.OnScrollChangeListener

person Govind    schedule 21.12.2016
comment
Потрясающий человек. Я потратил целый день серьезно на то, чтобы решить эту проблему, вы разбили ее на две строчки. Отлично ... Но теперь как мне получить видимые элементы и все такое, чтобы получать новые записи на сервере? - person Rahul Vats; 12.11.2017
comment
@RahulVats В приведенном выше коде, когда условие if выполнено, это означает, что пользователь полностью прокрутил страницу вниз и отображается последний элемент. Допустим, у вас есть 100 элементов, и изначально загружено 20 элементов. Если вышеуказанное условие выполнено, вы можете загрузить следующий набор данных (например, 21-40) со своего сервера. В любом случае, вы можете обратиться к этой ссылке для своего фактического запроса: stackoverflow.com/questions/40726438/ - person Govind; 13.11.2017
comment
Для вызова требуется уровень API 23 Я думаю, что если View выше RecyclerView не слишком сложен, мы должны реализовать его как другой тип элемента RecyclerView и удалить NestedScrollView, он также может сохранить технику повторного использования. - person Think Twice Code Once; 18.04.2018
comment
@ThinkTwiceCodeOnce Ему не нужен уровень API 23. Он поддерживает API 14. Подробнее об этом можно прочитать здесь - developer.android.com/reference/android/support/v4/widget/. - person Govind; 19.04.2018
comment
удивительный. Спасибо. - person Max Zonov; 31.05.2018
comment
@ThinkTwiceCodeOnce Когда вы устанавливаете этот слушатель, вы должны использовать NestedScrollView.OnScrollChangeListener (), а не View.OnScrollChangeListener (). - person Smiles; 20.10.2018
comment
Спасибо большое, отлично :) - person ErShakirAnsari; 04.11.2020

У меня была аналогичная проблема, хотя она была немного другой. В моем случае у меня был recycleview внутри фрагмента, в то время как NestedScrollView находился в content_main xml (часть активности).

Я обернул свое повторное представление, которое было внутри фрагмента, с помощью SwipeRefreshLayout

Это код моего фрагмента:

    <?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
    android:id="@+id/swipe_dummy"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

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

</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

Осталось только отключить SwipeRefreshLayout из кода.

mSwipeLayout.isEnabled = false

Если вы этого не сделаете, когда вы проведете пальцем вниз, появится значок бесконечного обновления. Я хотел поделиться этим решением на случай, если кому-то понадобится эта функция или возникнет эта проблема.

После того, как вы завершите recycleview с помощью SwipeRefreshLayout, вы увидите, что addOnScrollListener recycleview будет вызываться как обычно

person Anton Makov    schedule 11.04.2019