192

For my app I am using a RecyclerView inside a ScrollView where the RecyclerView has a height based on its content using this library. Scrolling is working but it's not working smoothly when I scroll over the RecyclerView. When I scroll over the ScrollView itself it is scrolling smoothly.

The code I am using to define the RecyclerView:

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

The RecyclerView in the 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" />
nalzok
  • 14,965
  • 21
  • 72
  • 139
Bart Bergmans
  • 4,061
  • 3
  • 28
  • 56
  • this solution work for me: http://stackoverflow.com/a/32390370/7308789 thank you – Houssin Boulla Mar 19 '17 at 19:44
  • 1
    @tahaDev what exactly not working in your case please elaborate more on that. Also, it seems like no provided solutions worked in your case, is it so? – Pravin Divraniya Jun 21 '19 at 05:51
  • Use `androidx.constraintlayout.widget.ConstraintLayout` which will solve your problem without any complex implementations – Saswata Jun 26 '19 at 13:19

18 Answers18

399

Try doing:

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

As an alternative, you can modify your layout using the support design library. I guess your current layout is something like:

<ScrollView >
   <LinearLayout >

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

   </LinearLayout >
</ScrollView >

You can modify that to:

<CoordinatorLayout >

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

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

</CoordinatorLayout >

However this is a longer road to take, and if you are OK with the custom linear layout manager, then just disable nested scrolling on the recycler view.

Edit (4/3/2016)

The v 23.2 release of the support libraries now includes a factory “wrap content” feature in all default LayoutManagers. I didn’t test it, but you should probably prefer it to that library you were using.

<ScrollView >
   <LinearLayout >

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

   </LinearLayout >
</ScrollView >
natario
  • 24,954
  • 17
  • 88
  • 158
  • 17
    To add to this answer: `setNestedScrollingEnabled(false)` only worked when I switched out the `ScrollView` for a `NestedScrollView` instead. – Richard Le Mesurier Feb 19 '16 at 14:19
  • 11
    For me, `setNestedScrollingEnabled(false)` gave me back smooth scrolling with my `RecyclerView` inside of a `ScrollView` - Thanks! But I still don't understand why that works...? What does it really mean to set nested scrolling false? – Micro Mar 15 '16 at 23:37
  • 33
    Note that `android:nestedScrollingEnabled="false"` only works for API 21+ but `v.setNestedScrollingEnabled(false)` is OK for <21. – Eric B. Jul 11 '16 at 20:40
  • This seems to work fine and saved me hours of work. Thanks. Is there any downside to using this solution? Because there are a lot of comments out there stating this is not a good solution, that you should not put scrolling views inside one another. – drod Jul 12 '16 at 20:59
  • @drod these comments are probably very old. Since nested scrolling was introduced, it is ok to nest scrolling views. – natario Jul 12 '16 at 21:01
  • 3
    For future reference, if anybody is experiencing `RecyclerView` wrap_content issue inside `ScrollView` that **only** happens on marshmallow/nougat (API 23, 24) devices, check my workaround at http://stackoverflow.com/a/38995399/132121 – Hossain Khan Aug 17 '16 at 11:34
  • @MicroR another problem pops up, nested view content will be scrolled out by recyclerview every time – EngineSense Aug 27 '16 at 11:27
  • 2
    A downside to this solution I'm experiencing right now is that the RecyclerView will not receive events in it's onScrollListener. Which I need because I want to fetch more data when I have only a certain amount of items in the recycler – Daniel W. Feb 07 '17 at 11:42
  • @Daniel if the recycler is wrap_content, it means it can't scroll. Maybe use a special item, like a progress bar, and fetch data onBindViewHolder of that particular item. – natario Mar 09 '17 at 07:40
  • `setNestedScrollingEnabled(false)` just make the recycleview fast..still dont know what happen..haha – ken Mar 14 '17 at 07:17
  • v.setNestedScrollingEnabled(false); This line helped a lot..Thanks – priyanka Mar 23 '17 at 11:32
  • setNestedScrollingEnabled(false) Solved my issue of scroll – Justcurious May 07 '17 at 22:38
  • This solution solved the scroll effect, I have continuation problem from this. I want to have drag option for the RecyclerView. I can only drop the item in the visible items on the screen. Not able to drop it on the items that are not visible in the list. I can achieve it if I remove NestedScrollView. I tried requestDisallowInterceptTouchEvent in onTouchEvent but no luck. Anyone had the same problem? – Sreeram Sunkara Oct 17 '17 at 14:36
  • Just added nestedScrollingEnabled="false" in recyclerview It worked for me. Thanks for ur support. – brijexecon Dec 28 '17 at 06:33
88

I only needed to use this:

mMyRecyclerView.setNestedScrollingEnabled(false);

in my onCreateView() method.

Thanks a lot!

AskNilesh
  • 67,701
  • 16
  • 123
  • 163
Victor Augusto
  • 2,406
  • 24
  • 20
30

You can use this way either :

Add this line to your recyclerView xml file :

android:nestedScrollingEnabled="false"

Or in java code :

RecyclerView.setNestedScrollingEnabled(false);

Hope this helped .

iDeveloper
  • 1,699
  • 22
  • 47
11

You can try with both the ways with XML and programmatically. But the issue you may face is (below API 21) by doing it with XML will not work . So it's better to set it programmatically in your Activity / Fragment.

XML code:

<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" /> 

Programmatically:

 recycleView = (RecyclerView) findViewById(R.id.recycleView);
 recycleView.setNestedScrollingEnabled(false);
Vishal Yadav
  • 3,642
  • 3
  • 25
  • 42
Pramod B
  • 1,652
  • 1
  • 10
  • 7
7

Using Nested Scroll View instead of Scroll View solved my problem

<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>
Siddy Hacks
  • 1,846
  • 14
  • 15
5

I had similar issues (I tried to create a nested RecyclerViews something like Google PlayStore design). The best way to deal with this is by subclassing the child RecyclerViews and overriding the 'onInterceptTouchEvent' and 'onTouchEvent' methods. This way you get complete control of how those events behave and eventually scrolling.

mahabudhi
  • 91
  • 1
  • 10
5

Replacing ScrollView with NestedScrollView resulted into smooth scrolling to the bottom.

minato
  • 2,028
  • 1
  • 18
  • 30
4

Every answer is same here. and i already used what everyone is suggested. Then i found that NestedScrollView is faster then ScrollView so

use

<androidx.core.widget.NestedScrollView

Instead of

<ScrollView

And use this as usual

recycleView.setNestedScrollingEnabled(false);
mr. groot
  • 334
  • 4
  • 18
3

Summary of all answers (Advantages & Disadvantages)

For single recyclerview

you can use it inside Coordinator layout.

Advantage - it will not load entire recyclerview items. So smooth loading.

Disadvantage - you can't load two recyclerview inside Coordinator layout - it produce scrolling problems

reference - https://stackoverflow.com/a/33143512/3879847

For multiple recylerview with minimum rows

you can load inside NestedScrollView

Advantage - it will scroll smoothly

Disadvantage - It load all rows of recyclerview so your activity open with delay

reference - https://stackoverflow.com/a/33143512/3879847

For multiple recylerview with large rows(more than 100)

You must go with recyclerview.

Advantage - Scroll smoothly, load smoothly

Disadvantage - You need to write more code and logic

Load each recylerview inside main recyclerview with help of multi-viewholders

ex:

MainRecyclerview

-ChildRecyclerview1 (ViewHolder1)

-ChildRecyclerview2 (ViewHolder2)

-ChildRecyclerview3 (ViewHolder3) 

-Any other layout   (ViewHolder4)

Reference for multi-viewHolder - https://stackoverflow.com/a/26245463/3879847

Community
  • 1
  • 1
Ranjithkumar
  • 16,071
  • 12
  • 120
  • 159
3

Kotlin

Set isNestedScrollingEnabled to false for every RecyclerView that is under the scrolling view

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

Using XML Layout

<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" />
Anand Tripathi
  • 14,556
  • 1
  • 47
  • 52
2

If you are using VideoView or heavy weight widgets in your childviews keep your RecyclerView with height wrap_content inside a NestedScrollView with height match_parent Then scrolling will work smooth as perfectly as you want it.

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>

Thanks Micro this was from your hint!

karthik

Yyy
  • 2,285
  • 16
  • 29
1

you can use ScrollView as a parent and NestedScrollView as a child. like this:-

       <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/CL1">
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/eventRV"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/CL1" />
    </androidx.core.widget.NestedScrollView>
0

XML code:

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

in java code :

  recycleView = (RecyclerView) findViewById(R.id.recycleView);
     recycleView.setNestedScrollingEnabled(false);
Mohsinali
  • 543
  • 7
  • 14
0

Or you can just set android:focusableInTouchMode="true" in your recycler view

Blue
  • 22,608
  • 7
  • 62
  • 92
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>

This code is working for in ConstraintLayout android

Hitesh sapra
  • 248
  • 2
  • 12
0

Simple Add this line into your JAVA class

list.setNestedScrollingEnabled(false);
0

I myself had this issue, there is a recycler view within a scrollview and the scroll doesn't seem to be smooth. The cause for my issue was having the scrollview on top of the recycler view which was not needed for my requirement. So after I removed the scrollview and added the android:scrollbars="vertical" for recycler view, the scrolling was smooth.

0

After 3 days of research, I solved smooth scroll issue in my project.

The problem is <layer-list> drawable set in the background of item_user.xml file so it takes GPU time for rendering that's why scrolling not smooth. So please dont use complex <layer-list> drawable in the background of adapter item.

My problem is solved by above solution, below option is not useful for me

  1. setNestedScrollingEnabled
  2. setHasFixedSize
  3. setItemViewCacheSize
Sanjayrajsinh
  • 15,014
  • 7
  • 73
  • 78