Recyclerview внутри ScrollView не прокручивается плавно


182

Для своего приложения я использую RecyclerViewвнутреннюю часть, ScrollViewгде RecyclerViewвысота зависит от ее содержимого с использованием этой библиотеки . Прокрутка работает, но не работает плавно, когда я прокручиваю RecyclerView. Когда я прокручиваю ScrollViewсам, он прокручивается плавно.

Код, который я использую для определения RecyclerView:

LinearLayoutManager friendsLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext(), android.support.v7.widget.LinearLayoutManager.VERTICAL, false);
mFriendsListView.setLayoutManager(friendsLayoutManager);
mFriendsListView.addItemDecoration(new DividerItemDecoration(getActivity().getApplicationContext(), null));

RecyclerViewВ ScrollView:

<android.support.v7.widget.RecyclerView
    android:layout_marginTop="10dp"
    android:layout_marginBottom="10dp"
    android:id="@+id/friendsList"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

это решение работает для меня: stackoverflow.com/a/32390370/7308789 спасибо
Houssin Boulla

1
@tahaDev, что именно не работает в вашем случае, пожалуйста, подробнее об этом. Кроме того, похоже, что в вашем случае никакие предоставленные решения не сработали, не так ли?
Pravin Divraniya

Использование, androidx.constraintlayout.widget.ConstraintLayoutкоторое решит вашу проблему без каких-либо сложных реализаций
Saswata

Ответы:


386

Попробуйте сделать:

RecyclerView v = (RecyclerView) findViewById(...);
v.setNestedScrollingEnabled(false);

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

<ScrollView >
   <LinearLayout >

       <View > <!-- upper content -->
       <RecyclerView > <!-- with custom layoutmanager -->

   </LinearLayout >
</ScrollView >

Вы можете изменить это на:

<CoordinatorLayout >

    <AppBarLayout >
        <CollapsingToolbarLayout >
             <!-- with your content, and layout_scrollFlags="scroll" -->
        </CollapsingToolbarLayout >
    </AppBarLayout >

    <RecyclerView > <!-- with standard layoutManager -->

</CoordinatorLayout >

Однако это более долгий путь, и если вы в порядке с настраиваемым менеджером линейной компоновки, просто отключите вложенную прокрутку в представлении ресайклера.

Изменить (4/3/2016)

v 23.2Выпуск поддержки библиотек в настоящее время включает в себя фабрику «содержание обертки» особенность во все по умолчанию LayoutManagers. Я не тестировал его, но вам, вероятно, следует предпочесть его той библиотеке, которую вы использовали.

<ScrollView >
   <LinearLayout >

       <View > <!-- upper content -->
       <RecyclerView > <!-- with wrap_content -->

   </LinearLayout >
</ScrollView >

16
Чтобы добавить к этому ответу: setNestedScrollingEnabled(false)сработало только тогда, когда я вместо этого переключил ScrollViewна NestedScrollView.
Ричард Ле Мезурье,

11
Для меня setNestedScrollingEnabled(false)вернул мне плавную прокрутку с моей RecyclerViewвнутренней стороной ScrollView- Спасибо! Но я все еще не понимаю, почему это работает ...? Что на самом деле означает установка ложной вложенной прокрутки?
Micro

33
Обратите внимание, что android:nestedScrollingEnabled="false"работает только для API 21+, но v.setNestedScrollingEnabled(false)подходит для <21.
Эрик Б.

3
Для справки в будущем, если у кого- RecyclerViewто внутри есть проблема с wrap_content, ScrollViewкоторая возникает только на устройствах с зефиром / нугой (API 23, 24), проверьте мой способ решения на stackoverflow.com/a/38995399/132121
Хоссейн Хан

2
Обратной стороной этого решения, с которым я сейчас сталкиваюсь, является то, что RecyclerView не будет получать события в onScrollListener. Что мне нужно, потому что я хочу получить больше данных, когда у меня есть только определенное количество элементов в переработчике
Дэниел В.

84

Мне нужно было только использовать это:

mMyRecyclerView.setNestedScrollingEnabled(false);

в моем onCreateView()методе.

Большое спасибо!


27

Вы можете использовать этот способ:

Добавьте эту строку в свой xml-файл recyclerView:

android:nestedScrollingEnabled="false"

Или в java-коде:

RecyclerView.setNestedScrollingEnabled(false);

Надеюсь, это помогло.


10
требуется Api 21+
Мухаммад Рияз

11

Вы можете попробовать как с XML, так и программно. Но проблема, с которой вы можете столкнуться, заключается в том, что (ниже API 21) выполнение этого с помощью XML не будет работать. Так что лучше установить его программно в Activity / Fragment.

Код XML:

<android.support.v7.widget.RecyclerView
      android:id="@+id/recycleView"
      android:layout_width="match_parent"
      android:visibility="gone"
      android:nestedScrollingEnabled="false"
      android:layout_height="wrap_content"
      android:layout_below="@+id/linearLayoutBottomText" /> 

Программно:

 recycleView = (RecyclerView) findViewById(R.id.recycleView);
 recycleView.setNestedScrollingEnabled(false);

6

Использование Nested Scroll View вместо Scroll View решило мою проблему

<LinearLayout> <!--Main Layout -->
   <android.support.v4.widget.NestedScrollView>
     <LinearLayout > <!--Nested Scoll View enclosing Layout -->`

       <View > <!-- upper content --> 
       <RecyclerView >


     </LinearLayout > 
   </android.support.v4.widget.NestedScrollView>
</LinearLayout>

5

У меня были похожие проблемы (я пытался создать вложенный RecyclerViews что-то вроде дизайна Google PlayStore). Лучший способ справиться с этим - создать подкласс дочернего RecyclerViews и переопределить методы onInterceptTouchEvent и onTouchEvent. Таким образом, вы получаете полный контроль над поведением этих событий и, в конечном итоге, прокруткой.



2

Резюме всех ответов (преимущества и недостатки)

Для одного ресайклервью

вы можете использовать его внутри макета Координатора.

Преимущество - он не загружает все элементы recyclerview. Такая плавная загрузка.

Недостаток - вы не можете загрузить два recyclerview внутри макета Координатора - возникают проблемы с прокруткой.

ссылка - https://stackoverflow.com/a/33143512/3879847

Для многократного повторного просмотра с минимальным количеством строк

вы можете загрузить внутри NestedScrollView

Преимущество - будет плавно прокручиваться

Недостаток - он загружает все строки recyclerview, поэтому ваша активность открывается с задержкой.

ссылка - https://stackoverflow.com/a/33143512/3879847

Для множественного повторного просмотра с большими строками (более 100)

Вы должны пойти с recyclerview.

Преимущество - плавная прокрутка, плавная загрузка

Недостаток - нужно писать больше кода и логики.

Загрузите каждый повторный просмотр в основной ресайклервью с помощью мультиэкранов

пример:

MainRecyclerview

-ChildRecyclerview1 (ViewHolder1)

-ChildRecyclerview2 (ViewHolder2)

-ChildRecyclerview3 (ViewHolder3) 

-Any other layout   (ViewHolder4)

Ссылка для multi-viewHolder - https://stackoverflow.com/a/26245463/3879847


1

Если вы используете VideoView или тяжелые виджеты в своих дочерних представлениях, сохраните RecyclerView с высотой wrap_content внутри NestedScrollView с высотой. match_parent Тогда прокрутка будет работать гладко, как вы этого хотите.

FYI,

<android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.RecyclerView
            android:layout_width="match_parent"
            android:nestedScrollingEnabled="false"
            android:layout_height="wrap_content"
            android:clipToPadding="false" />

</android.support.v4.widget.NestedScrollView>

Спасибо, Micro, это было с твоей подсказки!

Картик


1

Котлин

Набор isNestedScrollingEnabledдля falseдля каждого RecyclerView , который находится под прокрутку зрения

val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
recyclerView.isNestedScrollingEnabled = false

Использование XML-макета

<android.support.v7.widget.RecyclerView
    android:layout_marginTop="10dp"
    android:layout_marginBottom="10dp"
    android:id="@+id/friendsList"
    android:layout_width="match_parent"
    android:nestedScrollingEnabled="false"
    android:layout_height="wrap_content" />

0

Код XML:

<android.support.v4.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <android.support.v7.widget.RecyclerView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:clipToPadding="false" />

        </android.support.v4.widget.NestedScrollView>

в java-коде:

  recycleView = (RecyclerView) findViewById(R.id.recycleView);
     recycleView.setNestedScrollingEnabled(false);


0
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent">

        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent">

            <android.support.constraint.ConstraintLayout
                android:id="@+id/constraintlayout_main"
                android:layout_width="match_parent"
                android:layout_height="@dimen/layout_width_height_fortyfive"
                android:layout_marginLeft="@dimen/padding_margin_sixteen"
                android:layout_marginRight="@dimen/padding_margin_sixteen"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent">

                <TextView
                    android:id="@+id/textview_settings"
                    style="@style/textviewHeaderMain"
                    android:gravity="start"
                    android:text="@string/app_name"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent" />

            </android.support.constraint.ConstraintLayout>

            <android.support.constraint.ConstraintLayout
                android:id="@+id/constraintlayout_recyclerview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="@dimen/padding_margin_zero"
                android:layout_marginTop="@dimen/padding_margin_zero"
                android:layout_marginEnd="@dimen/padding_margin_zero"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/constraintlayout_main">

                <android.support.v7.widget.RecyclerView
                    android:id="@+id/recyclerview_list"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:nestedScrollingEnabled="false"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent" />

            </android.support.constraint.ConstraintLayout>

        </android.support.constraint.ConstraintLayout>

    </android.support.v4.widget.NestedScrollView>

</android.support.constraint.ConstraintLayout>

Этот код работает в ConstraintLayout android

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.