230

How to use RecyclerView inside NestedScrollView? RecyclerView content is not visible after setting adapter.

UPDATE layout code updated.

<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="@dimen/keyline_1">

    </RelativeLayout>

    <View
        android:id="@+id/separator"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#e5e5e5" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/conversation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

</android.support.v4.widget.NestedScrollView>
Tom11
  • 2,199
  • 6
  • 26
  • 50
Mecid
  • 4,150
  • 6
  • 28
  • 30
  • https://github.com/chrisbanes/cheesesquare – Marcin Orlowski Jun 24 '15 at 07:58
  • @Mecid There are no reasons to use a RecyclerView inside a ScrollView (or NestedScrollView). – Gabriele Mariotti Jun 24 '15 at 10:17
  • @GabrieleMariotti i have some content inside RelativeLayout, below relative layout i have recyclerview with comments, i need to scroll recyclerview with nestedscrollview, not separately. – Mecid Jun 24 '15 at 10:46
  • 2
    @Mecid you should never put a scrollable view inside another scrollable view. It is a general rule in Android. – Gabriele Mariotti Jun 24 '15 at 10:56
  • 7
    @GabrieleMariotti i know this rule, but NestedScrollView developed to fix this problem. – Mecid Jun 24 '15 at 20:12
  • 1
    It is not correct. NestedScrollView is just like ScrollView, but it supports acting as both a nested scrolling parent and child. In your case you have to define your own scrolling behaviour. – Gabriele Mariotti Jun 24 '15 at 20:22
  • @GabrieleMariotti thanks for your explanation – Mecid Jun 24 '15 at 20:44
  • @Mecid I met this problem and just set `android:minHieght=500dp` the recyclerview will show. While I do not know how to make recyclerview scroll with nestedscrollview. – acntwww Jun 25 '15 at 10:01
  • Could you please mark this answer as correct http://stackoverflow.com/a/31818632/4017501 I change from a Listview to a RecyclerView by that very same reason "RecyclerView implements NestedScrollingChild, RecyclerView should be able to be scrolled via NestedScrollView" for some how I forgot in the way, glad I found that answer (and that comment) – cutiko Oct 19 '15 at 17:28
  • @GabrieleMariotti I know the rule as well, but I don't get an idea how to "fix" it... here I asked something similar: http://stackoverflow.com/questions/34491137/nestedscrollview-and-recyclerview-issues-how-to-separate-them – Martin Pfeffer Dec 28 '15 at 10:18
  • just out of curiosity, why would you use a recyclerview inside a nestedscrollview? – Numan Karaaslan Sep 20 '19 at 17:37
  • @GabrieleMariotti how to scroll a screen if there are more than one recyclerview? – Arnold Brown Feb 04 '21 at 05:18
  • @Arnold Brown simply use nested layout and wrap layout inside linear layout using wrap content and setNestedScrollingEnabled(false) for recycle view – Atif AbbAsi Feb 04 '21 at 07:50
  • @AtifAbbAsi Thanks for your time. Yes I know this, I asked this for the comment "you should never put a scrollable view inside another scrollable view. It is a general rule in Android. " – Arnold Brown Feb 04 '21 at 09:15

26 Answers26

234

Replace your recyclerView with,

<android.support.v7.widget.RecyclerView
    android:id="@+id/conversation"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

here,

app:layout_behavior="@string/appbar_scrolling_view_behavior"

will manage the rest of things.

One more thing, no need to put your recyclerView inside NestedScrollView

Rahul Upadhyay
  • 3,297
  • 2
  • 19
  • 36
  • 39
    I can't understand why this solution doesn't get the most up-votes. It's not achieved with `NestedScrollView` but just with **`app:layout_behavior="@string/appbar_scrolling_view_behavior"`**. This is the key! – hata Oct 31 '15 at 17:56
  • 3
    @RahulUpadhyay this worked for me, but I think your last line is wrong, the RecyclerView doesn't show at all if it's inside a NestedScrollView. However, you're a superstar :D – Leon Nov 06 '15 at 09:01
  • 3
    It Works! just update recyclerview library compile 'com.android.support:recyclerview-v7:+' – Fabio Guerra Nov 07 '15 at 07:04
  • I like this way however wouldn't making the RecyclerView height `wrap_content` cause issues with scrolling if the RecyclerView adapter items have not been populated, because the height would be 0? Would it be better if height was `match_parent`? – Kevin Crain Jan 31 '16 at 06:14
  • @KevinCrain Its better to keep it to wrap_content as appbar_scrolling_view_behaviour will count the height of recyclerview itself. So no need to set match_parent. – Rahul Upadhyay Feb 15 '16 at 10:17
  • 2
    I have found another solution for this [Android Development](https://plus.google.com/107404572903933672672/posts/Y8BNZeoxrrY) It says you should use `setMinimumHeight` for the `RecyclerView` if it is within a `NestedScrollView` or it will be 0. Seems like something that is still in work for this widget. – UrielUVD Feb 17 '16 at 23:43
  • @Mecid If my solution worked for you then please accept this answer and mark it resolved. Thanks. – Rahul Upadhyay Feb 18 '16 at 09:19
  • app:layout_behavior="@string/appbar_scrolling_view_behavior" This line giving me parsing error. May be app or appbar is not consider as android key, that is why it giving me error. What to do ? – Ajay Sharma Mar 23 '16 at 05:27
  • @ajay, Can you please copy your xml view here? May be you forgot to mention app:xmlns in parent view. – Rahul Upadhyay Mar 23 '16 at 12:28
  • 1
    @RahulUpadhyay: Thanks for reply. May be that was the reason. But I have change all previous xml view to achieved UI that I have wanted without using above "app" keyword. Well, I have created a UI where 6 horizontal recycler view their in a Nested scroll view. – Ajay Sharma Mar 25 '16 at 04:42
  • This works if all you want is a recycler view there. If you in fact, as the title suggests, need a NestedScrollView with a RecyclerView (and something else) in it, then this is not useful. Personally I am trying to have a NestedScrollView with the appbar_scrolling_behaviour, and inside the NSV is a TextView followed by a RecyclerView. My current problem is that the RV becomes invisible. – JHH Apr 15 '16 at 08:30
  • @JHH, I've created the same UI as you suggest and I'm able to scroll whole container. Check this gist : https://gist.github.com/rahulupadhyay/0f507eff6f992a0051eec658729ae2fc – Rahul Upadhyay Apr 22 '16 at 09:00
  • 34
    This solution is intended to be used with `CoordinatorLayout`, `AppBarLayout`, and setting appropriate `layout_scrollFlags` on the child view(s) that should be scrolled with the `RecyclerView`. Not sure why this was omitted from the answer. Otherwise, this is a nice and simple solution. – Sanvywell Apr 29 '16 at 01:35
  • This is still lacks the recyclerview wrap_content of dynamic add and remove items . – EngineSense Aug 31 '16 at 07:27
  • 12
    I think it is very important to understand that RecyclerView's RECYCLING WON'T WORK here. As a result, if you have a long list of items it will appear with a noticeable UI freeze. – Gaket Nov 03 '17 at 11:00
  • 1
    @Sanvywell what if I am not using CoordinatorLayout? I need RecyclerView inside NestedScrollView and this solution is not working. – Wijay Sharma Jan 03 '18 at 05:03
  • 1
    idk why but i had to add a `NestedScrollView ` for scrolling to work. i had a two views above `RecyclerView` – MMK Feb 01 '20 at 19:10
  • 1
    Worked for me. I don't understand @Gaket's comment because my recyclerview is recycling working fine. – Pooja Sep 21 '20 at 21:40
123

UPDATE 1

Since Android Support Library 23.2.0 there were added method setAutoMeasureEnabled(true) for LayoutManagers. It makes RecyclerView to wrap it's content and works like a charm.
http://android-developers.blogspot.ru/2016/02/android-support-library-232.html

So just add something like this:

    LayoutManager layoutManager = new LinearLayoutManager(this);
    layoutManager.setAutoMeasureEnabled(true);
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setNestedScrollingEnabled(false);


UPDATE 2

Since 27.1.0 setAutoMeasureEnabled is deprecated, so you should provide custom implementation of LayoutManager with overridden method isAutoMeasureEnabled()

But after many cases of usage RecyclerView I strongly recommend not to use it in wrapping mode, cause this is not what it is intended for. Try to refactor whole your layout using normal single RecyclerView with several items' types. Or use approach with LinearLayout that I described below as last resort


Old answer (not recommended)

You can use RecyclerView inside NestedScrollView. First of all you should implement your own custom LinearLayoutManager, it makes your RecyclerView to wrap its content. For example:

public class WrappingLinearLayoutManager extends LinearLayoutManager
{

    public WrappingLinearLayoutManager(Context context) {
        super(context);
    }

    private int[] mMeasuredDimension = new int[2];

    @Override
    public boolean canScrollVertically() {
        return false;
    }

    @Override
    public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state,
            int widthSpec, int heightSpec) {
        final int widthMode = View.MeasureSpec.getMode(widthSpec);
        final int heightMode = View.MeasureSpec.getMode(heightSpec);

        final int widthSize = View.MeasureSpec.getSize(widthSpec);
        final int heightSize = View.MeasureSpec.getSize(heightSpec);

        int width = 0;
        int height = 0;
        for (int i = 0; i < getItemCount(); i++) {
            if (getOrientation() == HORIZONTAL) {
                measureScrapChild(recycler, i,
                        View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                        heightSpec,
                        mMeasuredDimension);

                width = width + mMeasuredDimension[0];
                if (i == 0) {
                    height = mMeasuredDimension[1];
                }
            } else {
                measureScrapChild(recycler, i,
                        widthSpec,
                        View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                        mMeasuredDimension);

                height = height + mMeasuredDimension[1];
                if (i == 0) {
                    width = mMeasuredDimension[0];
                }
            }
        }

        switch (widthMode) {
            case View.MeasureSpec.EXACTLY:
                width = widthSize;
            case View.MeasureSpec.AT_MOST:
            case View.MeasureSpec.UNSPECIFIED:
        }

        switch (heightMode) {
            case View.MeasureSpec.EXACTLY:
                height = heightSize;
            case View.MeasureSpec.AT_MOST:
            case View.MeasureSpec.UNSPECIFIED:
        }

        setMeasuredDimension(width, height);
    }

    private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
            int heightSpec, int[] measuredDimension) {

        View view = recycler.getViewForPosition(position);
        if (view.getVisibility() == View.GONE) {
            measuredDimension[0] = 0;
            measuredDimension[1] = 0;
            return;
        }
        // For adding Item Decor Insets to view
        super.measureChildWithMargins(view, 0, 0);
        RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
        int childWidthSpec = ViewGroup.getChildMeasureSpec(
                widthSpec,
                getPaddingLeft() + getPaddingRight() + getDecoratedLeft(view) + getDecoratedRight(view),
                p.width);
        int childHeightSpec = ViewGroup.getChildMeasureSpec(
                heightSpec,
                getPaddingTop() + getPaddingBottom() + getDecoratedTop(view) + getDecoratedBottom(view),
                p.height);
        view.measure(childWidthSpec, childHeightSpec);

        // Get decorated measurements
        measuredDimension[0] = getDecoratedMeasuredWidth(view) + p.leftMargin + p.rightMargin;
        measuredDimension[1] = getDecoratedMeasuredHeight(view) + p.bottomMargin + p.topMargin;
        recycler.recycleView(view);
    }
}

After that use this LayoutManager for your RecyclerView

recyclerView.setLayoutManager(new WrappingLinearLayoutManager(getContext()));

But you also should call those two methods:

recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(false);

Here setNestedScrollingEnabled(false) disable scrolling for RecyclerView, so it doesn't intercept scrolling event from NestedScrollView. And setHasFixedSize(false) determine that changes in adapter content can change the size of the RecyclerView

Important note: This solution is little buggy in some cases and has problems with perfomance, so if you have a lot of items in your RecyclerView I'd recommend to use custom LinearLayout-based implementation of list view, create analogue of Adapter for it and make it behave like ListView or RecyclerView

smbd uknow
  • 2,134
  • 1
  • 11
  • 22
  • 22
    Caution! Don't use this if you have a lot of items in your `RecyclerView`. – Brais Gabin Nov 05 '15 at 11:17
  • 1
    @BraisGabin, you're right: setHasFixedSize(false) causes multiple refreshing of RecyclerView, so if it has a lot of items, it will work very slow. In those cases I use LinearLayout with a kind of custom "adapter" for it to make it behave like ListView or RecyclerView – smbd uknow Nov 05 '15 at 13:50
  • 1
    Thanks alot! Saved me hours. By the way, the last item decoration is not displayed with this layout manager (and only with this one), possible bug? – Jjang Nov 06 '15 at 21:00
  • @Jjang, it seems like a bug. I had a problem with displaying last item on nexus devices. And as I wrote in upper comment in some cases I prefer using custom LinearLayout-based list implementation – smbd uknow Nov 24 '15 at 07:55
  • A tip, if you only have a `NestedScrollView` because of the template and will only have a `RecyclerView` (and/or `SwipeRefreshLayout`) just remove the `NestedScrollView`, then things will work as expected with using the regular `LinearLayoutManager`. – Victor Häggqvist Dec 23 '15 at 00:01
  • Wow! After writing my own `WrapContentGridLayoutManager` and returning false on _canScrollVertically_, my `RecyclerView` kept intercepting scroll events from `NestedScrollView`. Those two lines _setNestedScrollingEnabled_ and _setHasFixedSize_ made my day. Thanks! – Gero Dec 24 '15 at 21:48
  • recyclerView.setNestedScrollingEnabled(false); With my custom linear layout manager saved my day.Thank you very very much – Manikanta Dec 30 '15 at 11:16
  • This is crashing when we bind list without any data – Mehul Ranpara Nov 25 '16 at 13:21
  • 2
    setAutoMeasureEnabled is deprecated as of API level 27.1.0 https://developer.android.com/reference/android/support/v7/widget/RecyclerView.LayoutManager.html#setAutoMeasureEnabled(boolean) – Dika Mar 22 '18 at 18:04
  • 2
    override boolean isAutoMeasureEnabled () instead. it Returns whether the measuring pass of layout should use the AutoMeasure mechanism of RecyclerView or if it should be done by the LayoutManager's implementation of onMeasure(Recycler, State, int, int). This method returns false by default (it actually returns the value passed to the deprecated setAutoMeasureEnabled(boolean)) and should be overridden to return true if a LayoutManager wants to be auto measured by the RecyclerView. If this method is overridden to return true, onMeasure(Recycler, State, int, int) should not be overridden. – Peterstev Uremgba Nov 02 '18 at 15:54
  • `recyclerView.setNestedScrollingEnabled(false);` only adding this line help me out to fix the problem. My problem was I have 4 different recyclerview inside of one NestedScrollView parent. – Eren Utku Nov 07 '18 at 15:25
  • @ErenUtku if it possible than try to replace your layout with single RecyclerView with resolving different itemTypes in its adapter (for example this lib https://github.com/sockeqwe/AdapterDelegates makes it much easier). It would be much better for performance – smbd uknow Nov 08 '18 at 10:14
118
  1. You need to use support library 23.2.0 (or) above

  2. and RecyclerView height will be wrap_content.

  3. recyclerView.setNestedScrollingEnabled(false)

But by doing this the recycler pattern doesn't work. (i.e all the views will be loaded at once because wrap_content needs the height of complete RecyclerView so it will draw all child Views at once. No view will be recycled). Try not to use this pattern unless it is really required. Try to use viewType and add all other views that need to scroll to RecyclerView rather than using RecyclerView in Scrollview. The performance impact will be very high.

To make it simple "it just acts as LinearLayout with all the child views"

Boken
  • 3,207
  • 9
  • 25
  • 31
Ashok Varma
  • 3,159
  • 2
  • 24
  • 41
  • 7
    Thanks @Ashok. Setting `recyclerView.setNestedScrollingEnabled(false)` helped me to have a smooth scroll. – Shubhral Jun 10 '16 at 11:45
  • 8
    This should be the accepted answer ! cause it well point it out that No view will be recycled and all the view will be drawn at once. – M'hamed Jul 15 '16 at 02:28
  • 3
    @AshokVarma , same issue i am facing now. but scroll is working fine inside recyclerView but i could not implement Endless scroll for recyclerview beacuse all views of recyclerview draws at once so it leads to keep on calling web service. so how can i handle this? – Anantha Babu Jan 13 '17 at 04:54
  • @AnanthaBabu instead of using recyclerview in a scrollview. convert all items in the scrollview to items in recycler view. you can use recyclerviews view type and paint different kinds of layouts. There are some good libraries to handle these as well (Use libraries if you have really complicated view structure and if you want reusable components). – Ashok Varma Jan 17 '17 at 03:25
  • 2
    @AshokVarma is there any solution for the recycler behavior issue? I dont want recyclerview to draw all the children at one shot. – andro-girl Feb 15 '17 at 12:34
  • @andro-girl you can use recycler view and convert all views of your scrollview as items in recycler view. Check getItemViewType() method in recycler adapter – Ashok Varma Feb 18 '17 at 20:49
  • @AshokVarma what libraries do you recommend? – Janusz Hain Oct 24 '18 at 11:02
36

You can use android:fillViewport="true" to make NestedScrollView measure the RecyclerView. The RecyclerView will fill the remaining height. so if you want to scroll the NestScrollView, you can set the RecyclerView's minHeight.

Vlad Schnakovszki
  • 7,446
  • 5
  • 74
  • 105
zayn
  • 600
  • 5
  • 12
  • 22
    if you have a recyclerview of 200 items and you do this, the nestedscrollview will expand to fill the entire 200 items! – RJFares Apr 08 '17 at 20:08
  • 2
    @RJFares That's never happened. I try a demo and use LayoutInspector to inspect the layout, it just work well. Can you provider your recyclerView's versions? – zayn Apr 11 '17 at 01:32
  • @zayn I know this is an old answer but we need to correct this that RJFares is right. RecyclerView no matter what implementation when put inside a NestedScrollView will stop recycling item thus if you have 200 items on it, even items that are not visible in the screen will consume memory and will not be recycled which cause OOM. – Mihae Kheel Mar 12 '21 at 13:44
26

Simply adding recyclerView.setNestedScrollingEnabled(false); before setAdapter itself worked for me. I didn't add app:layout_behavior="@string/appbar_scrolling_view_behavior" anywhere & didn't set any custom layout manager

<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="15dp"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/white"
                android:text="Some Text..."
                android:padding="15dp" />

        </LinearLayout>

        <LinearLayout
            android:orientation="vertical"
            android:padding="15dp"
            android:layout_marginTop="10dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Quick Links"
                android:textColor="@color/black"
                android:textStyle="bold"
                android:textAllCaps="true"
                android:paddingLeft="20dp"
                android:drawableLeft="@drawable/ic_trending_up_black_24dp"
                android:drawablePadding="10dp"
                android:layout_marginBottom="10dp"
                android:textSize="16sp"/>

            <View
                android:layout_width="fill_parent"
                android:layout_height="1dp"
                android:background="#efefef"/>

            <android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/recyclerview"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </LinearLayout>

    </LinearLayout>

</android.support.v4.widget.NestedScrollView>
SMR
  • 6,320
  • 2
  • 32
  • 55
22

This is what working for me

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.v4.widget.NestedScrollView>
Ness Tyagi
  • 1,830
  • 21
  • 18
  • 4
    You can remove the second *app:layout_behavior="@string/appbar_scrolling_view_behavior"* As behavior only works for CoordinatorLayout direct childs. – Pepster Aug 16 '16 at 15:10
  • 2
    In addition, it is important to mention that you should have _Coordinator layout_ as your root layout. It is not always true. – Gaket Dec 14 '16 at 14:29
  • Can you use `CoordinatorLayout` in a dialog? – casolorz Oct 02 '20 at 19:13
13

For androidx it's called androidx.core.widget.NestedScrollView - and it scrolls alike butter with properties isScrollContainer and measureAllChildren enabled:

<!-- Scrolling Content -->
<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"

    android:isScrollContainer="true"
    android:measureAllChildren="true"

    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fastScrollEnabled="true"
        android:scrollbarStyle="insideInset"
        android:scrollbars="vertical"
        android:splitMotionEvents="false"
        android:verticalScrollbarPosition="right"/>

</androidx.core.widget.NestedScrollView>
Martin Zeitler
  • 49,224
  • 12
  • 97
  • 156
10

There is a simple and testing code u may check

<android.support.v4.widget.NestedScrollView
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:fillViewport="true"
     app:layout_behavior="@string/appbar_scrolling_view_behavior">
    <android.support.v7.widget.RecyclerView
           android:layout_width="match_parent"
           android:layout_height="match_parent"/>
   </android.support.v4.widget.NestedScrollView>
Hakim Khan
  • 293
  • 5
  • 9
7

Try to use this library - https://github.com/serso/android-linear-layout-manager.

LayoutManager of the library makes RecyclerView wraps its contents. In this case RecyclerView will be "as big as inner views", so it will not have a scrollbars and user will use scrolling abilities of NestedScrollView. Therefore, it will not be ambiguous like "scrollable inside scrollable".

alcsan
  • 5,793
  • 1
  • 21
  • 18
  • 1
    This is the class of LinearLayoutManager from this library: https://github.com/serso/android-linear-layout-manager/blob/master/lib/src/main/java/org/solovyev/android/views/llm/LinearLayoutManager.java – Ninja Coding Feb 02 '16 at 16:38
6

Here is the code that I'm using to avoid scrolling issues:

mRecyclerView = (RecyclerView) view.findViewById(android.R.id.list);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mRecyclerView.getLayoutManager().setAutoMeasureEnabled(true);
mRecyclerView.setNestedScrollingEnabled(false);
mRecyclerView.setHasFixedSize(false);
Anton Tananaev
  • 2,158
  • 1
  • 19
  • 39
6

I used RecyclerView inside a NestedScrollView and it worked for me. The only gotcha I had to keep in mind was that a NestedScrollView takes only one child view. So in my case I used of LienearLayout viewgroup which was housing my RecyclerView plus a number of other views that I needed.

I experience one issue putting my RecyclerView inside the NestedScrollView. I realized that scrolling the content of my RecyclerView slacked.

I later realized that my RecyclerView was receiving the scrolling event and therefore was conflicting with the scrolling behavior of the NestedScrollView.

So to solve that problem, I had to disable the scroll functionality of my RecyclerView with this method movieListNewRecyclerView.setNestedScrollingEnabled(false);

You can checkout my Instagram for a short video of what I actually did. This is my instagram handle ofelix03

Click this image to see what I did

Boken
  • 3,207
  • 9
  • 25
  • 31
Felix Otoo
  • 69
  • 1
  • 2
5

I have Viewpager and RecyclerView inside the NestedScrollView. After adding below lines

recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(false);

I solved slow scroll and scroll lag issue.

Isham
  • 402
  • 4
  • 14
4

if you want to use RecyclerView in NestedScrollView this is a simple tricky, just set :

RecyclerView

  • recyclerView.setHasFixedSize(false) (java/kt)

  • android:nestedScrollingEnabled="false"

  • android:layout_height="wrap_content"

  • android:overScrollMode="never"

NestedScrollView

  • android:fillViewport="true"

this is work for me, and you can use many RecyclerView in NestedScrollView with this too.

im-o
  • 111
  • 2
  • 6
3

If you are using RecyclerView-23.2.1 or later. Following solution will work just fine:

In your layout add RecyclerView like this:

<android.support.v7.widget.RecyclerView
        android:id="@+id/review_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical" />

And in your java file:

RecyclerView mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager=new LinearLayoutManager(getContext());
layoutManager.setAutoMeasureEnabled(true);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setAdapter(new YourListAdapter(getContext()));

Here layoutManager.setAutoMeasureEnabled(true); will do the trick.

Check out this issue and this developer blog for more information.

uniruddh
  • 4,218
  • 3
  • 47
  • 85
  • Be careful using "mRecyclerView.setHasFixedSize(true);" though. You can use it only if you don't add or remove items from recycler view at runtime. – Gaket Dec 14 '16 at 14:01
3

If you are using RecyclerView ScrollListener inside NestedScrollView, addOnScrollListener listener not working properly if you are used both.

Use this code.

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState); 
              ......
        }
    });

this code working fine RecyclerView ScrollListener inside NestedScrollView.

thanks

Rahul
  • 344
  • 4
  • 13
2

You can't use a recycler view within a nested scroll view. It's not intended to contain further scrollable views but it's because it's a child of a scrolling layout itself that you need the nested scrolling view. I had the same issue but in the end I moved my textview to be a headerview within the recyclerview, made the recyclerview a direct child of the coordinator layout and deleted the nested scroll view. Then all my problems were gone.

Barry Irvine
  • 12,074
  • 2
  • 18
  • 27
  • 8
    Since `RecyclerView` implements `NestedScrollingChild`, `RecyclerView` should be able to be scrolled via `NestedScrollView`. – Jade Oct 14 '15 at 04:41
  • I just voted to reject http://stackoverflow.com/review/suggested-edits/9907622 based purely upon the English mistakes, but there may be content of value in there - anybody passing by with knowledge of the subject matter should take a look and see if they can clean it up. If there's nothing useful there, flag this comment of mine for deletion by the mods. – Mark Amery Oct 19 '15 at 17:56
2

One solution to keep the recycling feature of the recyclerview and avoiding the recyclerview to load all your data is setting a fix height in the recyclerview itself. By doing this the recyclerview is limited only to load as much as its height can show the user thus recycling its element if ever you scroll to the bottom/top.

Christian Callelero
  • 664
  • 1
  • 7
  • 16
2

There are a lot of good answers. The key is that you must set nestedScrollingEnabled to false. As mentioned above you can do it in java code:

mRecyclerView.setNestedScrollingEnabled(false);

But also you have an opportunity to set the same property in xml code (android:nestedScrollingEnabled="false"):

 <android.support.v7.widget.RecyclerView
 android:id="@+id/recyclerview"
 android:nestedScrollingEnabled="false"
 android:layout_width="match_parent"
 android:layout_height="match_parent" />
Alex Misiulia
  • 963
  • 10
  • 14
2
nestedScrollView.setNestedScrollingEnabled(true);

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            //...
        }
    });


<androidx.core.widget.NestedScrollView
    android:id="@+id/nested"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    android:layout_below="@id/appBarLayout_orders"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"> 

    <androidx.constraintlayout.widget.ConstraintLayout ...

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"/>
Braian Coronel
  • 17,823
  • 4
  • 30
  • 33
1

I had to implement CoordinatorLayout with toolbar scrolling and it just took me all the day messing around this. I've got it working by removing NestedScrollView at all. So I'm just using RelativeLayout at the root.

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

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_nearby"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</RelativeLayout>
Bogdan Ustyak
  • 4,507
  • 2
  • 16
  • 15
1

do not use recyclerView inside NestedScrollView. it may cause cascading problems! I suggest using ItemViewTypes in RecyclerView for handling multiple kinds of views. just add a RecyclerView with match_parent width and height. then in your recyclerViewAdapter override getItemViewType and use position for handling what layout to be inflated. after that you can handle your view holder by using onBindViewHolder method.

Hossein Karami
  • 540
  • 7
  • 10
0

In my case, this is what works for me

  • Put android:fillViewport="true" inside NestedScrollView.

  • Make the height of RecyclerView to wrap_content, i.e android:layout_height="wrap_content"

  • Add this in RecyclerView android:nestedScrollingEnabled="false"

OR

Programmatically, in your Kotlin class

recyclerView.isNestedScrollingEnabled = false

mRecyclerView.setHasFixedSize(false)

0

At least as far back as Material Components 1.3.0-alpha03, it doesn't matter if the RecyclerView is nested (in something other than a ScrollView or NestedScrollView). Just put app:layout_behavior="@string/appbar_scrolling_view_behavior" on its top level parent that's a sibling of the AppBarLayout in the CoordinatorLayout.

This has been working for me when using a single Activity architecture with Jetpack Naviagation, where all Fragments are sharing the same AppBar from the Activity's layout. I make the FragmentContainer the direct child of the CoordinatorLayout that also contains the AppBarLayout, like below. The RecyclerViews in the various fragments are scrolling normally and the AppBar folds away and reappears as expected.

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:id="@+id/coordinatorLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/nav_host_fragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            app:defaultNavHost="true"
            app:navGraph="@navigation/mobile_navigation"/>

        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appbar_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:liftOnScroll="true">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:minHeight="?attr/actionBarSize"
                android:theme="?attr/actionBarTheme"
                app:layout_scrollFlags="scroll|enterAlways|snap" />

        </com.google.android.material.appbar.AppBarLayout>

    </androidx.coordinatorlayout.widget.CoordinatorLayout>

liftOnScroll (used to for app bars to look like they have zero elevation when at the top of the page) works if each fragment passes the ID of its RecyclerView to AppBarLayout.liftOnScrollTargetViewId in Fragment.onResume. Or pass 0 if the Fragment doesn't scroll.

Tenfour04
  • 39,254
  • 8
  • 47
  • 96
-1

I have used this awesome extension (written in kotlin but can be also used in Java)

https://github.com/Widgetlabs/expedition-nestedscrollview

Basically you get the NestedRecyclerView inside any package lets say utils in your project, then just create your recyclerview like

 <com.your_package.utils.NestedRecyclerView
      android:id="@+id/rv_test"
      android:layout_width="match_parent"
      android:layout_height="match_parent" />

Check this awesome article by Marc Knaup

https://medium.com/widgetlabs-engineering/scrollable-nestedscrollviews-inside-recyclerview-ca65050d828a

Gastón Saillén
  • 9,076
  • 4
  • 39
  • 58
-1

For my case the child of NestedScrollview is ConstraintLayout. It is not working as expected i replaced it to LinearLayout. Maybe it helps someone.

<androidx.core.widget.NestedScrollView 
  android:id="@+id/nestedScrollView" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent">

  <LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:descendantFocusability="blocksDescendants">

    <androidx.recyclerview.widget.RecyclerView
      android:id="@+id/recyclerView"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:nestedScrollingEnabled="false" />

  </LinearLayout>
</androidx.core.widget.NestedScrollView>
Boken
  • 3,207
  • 9
  • 25
  • 31
nAkhmedov
  • 2,913
  • 4
  • 29
  • 59
-6

RecyclerView with NestedScrollView

    <android.support.v7.widget.RecyclerView
    android:id="@+id/rv"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />