How to use RecyclerView inside NestedScrollView?
Asked Answered
S

27

250

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>
Sweptback answered 23/6, 2015 at 10:18 Comment(13)
github.com/chrisbanes/cheesesquareInfeld
@Sweptback There are no reasons to use a RecyclerView inside a ScrollView (or NestedScrollView).Berwick
@GabrieleMariotti i have some content inside RelativeLayout, below relative layout i have recyclerview with comments, i need to scroll recyclerview with nestedscrollview, not separately.Sweptback
@Sweptback you should never put a scrollable view inside another scrollable view. It is a general rule in Android.Berwick
@GabrieleMariotti i know this rule, but NestedScrollView developed to fix this problem.Sweptback
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.Berwick
@Sweptback 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.Flavopurpurin
Could you please mark this answer as correct https://mcmap.net/q/115817/-how-to-use-recyclerview-inside-nestedscrollview 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)Warwick
@GabrieleMariotti I know the rule as well, but I don't get an idea how to "fix" it... here I asked something similar: #34491637Psychodiagnosis
just out of curiosity, why would you use a recyclerview inside a nestedscrollview?Fleischman
@GabrieleMariotti how to scroll a screen if there are more than one recyclerview?Algicide
@Arnold Brown simply use nested layout and wrap layout inside linear layout using wrap content and setNestedScrollingEnabled(false) for recycle viewAirsick
@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. "Algicide
T
248

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

Turnheim answered 23/9, 2015 at 9:0 Comment(21)
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!Uneducated
@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 :DCornie
It Works! just update recyclerview library compile 'com.android.support:recyclerview-v7:+'Kutchins
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?Symposiarch
@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.Turnheim
I have found another solution for this Android Development 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.Beacon
@Sweptback If my solution worked for you then please accept this answer and mark it resolved. Thanks.Turnheim
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 ?Carminecarmita
@ajay, Can you please copy your xml view here? May be you forgot to mention app:xmlns in parent view.Turnheim
@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.Carminecarmita
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.Salzburg
@JHH, I've created the same UI as you suggest and I'm able to scroll whole container. Check this gist : gist.github.com/rahulupadhyay/0f507eff6f992a0051eec658729ae2fcTurnheim
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.Drumbeat
This is still lacks the recyclerview wrap_content of dynamic add and remove items .Violetavioletta
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.Ritter
@Sanvywell what if I am not using CoordinatorLayout? I need RecyclerView inside NestedScrollView and this solution is not working.Communism
idk why but i had to add a NestedScrollView for scrolling to work. i had a two views above RecyclerViewAxel
Worked for me. I don't understand @Gaket's comment because my recyclerview is recycling working fine.Bitolj
YOU CAN'T USE WRAP_CONTENT for large data lists or when you have pagination! your reclerview will be too big and will load all pages at once, eat cpu and memoryUnwished
@Bitolj and you won't understand until you set very large list or use pagination, if your data is limited to max 50 items then it's fine and you won't notice anythingUnwished
@Unwished Dont understand your comment. Pooja's comment is correct. I just checked and recycling works as expected. I have a list with 300 items and only 10 of them initially loaded because they are visible on scree. Other items loaded on demand as soon as they appear on screenRafter
A
139
  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"

Atalante answered 2/5, 2016 at 7:56 Comment(10)
Thanks @Ashok. Setting recyclerView.setNestedScrollingEnabled(false) helped me to have a smooth scroll.Dudley
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.Easternmost
@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?Bellyband
@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).Atalante
@AshokVarma is there any solution for the recycler behavior issue? I dont want recyclerview to draw all the children at one shot.Sodden
@Sodden you can use recycler view and convert all views of your scrollview as items in recycler view. Check getItemViewType() method in recycler adapterAtalante
@AshokVarma what libraries do you recommend?Jadajadd
you can't use wrap_content with pagination, it will load all pages at once and height of recyclerview will be very big and it will eat a lot of cpu, memory and so onUnwished
instagram doesn't use viewtype for stories header, because it remembers the position of header when come back to the top of screenUnwished
What if I want to use horizontal recycler view inside a NestedScrollView ?Ginseng
H
128

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

Heptamerous answered 23/9, 2015 at 9:42 Comment(12)
Caution! Don't use this if you have a lot of items in your RecyclerView.Pretended
@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 RecyclerViewHeptamerous
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?Stepsister
@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 implementationHeptamerous
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.Averment
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!Portly
recyclerView.setNestedScrollingEnabled(false); With my custom linear layout manager saved my day.Thank you very very muchLacker
This is crashing when we bind list without any dataBoob
setAutoMeasureEnabled is deprecated as of API level 27.1.0 developer.android.com/reference/android/support/v7/widget/…Juanajuanita
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.Persnickety
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.Morrill
@ErenUtku if it possible than try to replace your layout with single RecyclerView with resolving different itemTypes in its adapter (for example this lib github.com/sockeqwe/AdapterDelegates makes it much easier). It would be much better for performanceHeptamerous
N
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.

Narva answered 25/7, 2015 at 8:30 Comment(4)
if you have a recyclerview of 200 items and you do this, the nestedscrollview will expand to fill the entire 200 items!Holism
@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?Narva
@Narva 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.Nonperformance
yes and if you have pagination it will load all pages, which is bad for cpu, memory and internet. I wonder how Instagram implemented stories header + recyclerview, at first I thought it was a header view holder but it's not, because it even remembers last horizontal position of stories header when you scroll back to top of screen, so it's something elseUnwished
E
27

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>
Egan answered 11/7, 2016 at 9:37 Comment(4)
But now it does not recycle views anymore?Room
No, it will recycle, isn't it?Egan
no it doesn't, i tried with a very complex layout with 200 items the nestedscrollview just expands to the size of its children so it will expand, therefore no recycling will happen @MarkBuikema did you manage to find a better solution?Holism
I want to scroll screen to RecyclerView programmatically is it possible inside the NestedScrollView?Gaekwar
E
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>
Exhaustive answered 23/5, 2016 at 19:12 Comment(3)
You can remove the second app:layout_behavior="@string/appbar_scrolling_view_behavior" As behavior only works for CoordinatorLayout direct childs.Plastid
In addition, it is important to mention that you should have Coordinator layout as your root layout. It is not always true.Ritter
Can you use CoordinatorLayout in a dialog?Karee
B
15

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>
Butadiene answered 26/5, 2019 at 8:42 Comment(1)
Recycling is still disabled with this solution if I'm not mistaken.Carbonization
P
12

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>
Pourpoint answered 24/9, 2016 at 7:4 Comment(0)
R
11

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

Rudman answered 12/1, 2017 at 9:11 Comment(1)
my layout structure is just like yours, and actually the recyclerview don't need to setNestedScrollingEnabled(false), it works well with or without that method. Give it a try!Narwhal
W
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".

Worrywart answered 25/11, 2015 at 17:46 Comment(1)
This is the class of LinearLayoutManager from this library: github.com/serso/android-linear-layout-manager/blob/master/lib/…Bibby
G
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);
Giesser answered 3/11, 2016 at 2:57 Comment(0)
T
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.

Tort answered 30/9, 2016 at 12:35 Comment(2)
Don't you mean recyclerView.setHasFixedSize(true);?Kistna
No, it's setHasFixedSize(false) and layout_height="wrap_content".Sosthenna
W
5

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.

Wolter answered 8/10, 2020 at 0:25 Comment(0)
F
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.

Forby answered 24/7, 2016 at 10:41 Comment(1)
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.Ritter
E
3

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" />
Ellita answered 4/4, 2019 at 6:55 Comment(3)
but then it's page is not scrollableUnwished
@user924, scroll inside RecyclerView will be disabled and it will be scrolled together with screen content. This isn't a solution If you need to have scroll inside RecyclerView elementsEllita
it's not going to be scrolled with content if you set match_parent for android:layout_height for RecyclerViewUnwished
K
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

Kazmirci answered 4/7, 2019 at 5:48 Comment(0)
J
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.

Josefinejoseito answered 15/11, 2018 at 21:49 Comment(0)
M
2

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.

https://stacklearn.ir

Moa answered 16/8, 2019 at 15:54 Comment(3)
Sometimes such a thing is impossible. For example when inside the scrolling content there is a ViewPager of Fragments, and each has a RecyclerView in it.Vowel
@androiddeveloper - I think its the time of jetpack compose. we are wasting our time in these cases :)Moa
jetpack compose is very different. It's not a solution. Just switching to a very different way. Besides, it has its own issues, according to what people told me.Vowel
G
2

You can use my sample code

    <?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <LinearLayout
        android:id="@+id/fl_all_brand"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:context=".view.fragment.AllBrandFragment">

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

            <LinearLayout
                android:id="@+id/fl_all_brand1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"

                android:orientation="vertical">


                <!--<include layout="@layout/content_home" />-->

                <TextView
                    android:id="@+id/tv_title"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_marginStart="@dimen/_15sdp"
                    android:layout_marginTop="@dimen/_20sdp"
                    android:fontFamily="@font/lexend_semibold"
                    android:text="@string/DISPLAY_LIGHTS"
                    android:textColor="@color/gray_scale_placehold"
                    android:textSize="@dimen/_16ssp" />


                <LinearLayout
                    android:id="@+id/recyclerLayout"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/_280sdp">


                    <androidx.recyclerview.widget.RecyclerView
                        android:id="@+id/recyclerviewobj"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_marginStart="@dimen/_10sdp"
                        android:layout_marginTop="@dimen/_20sdp"
                        android:layout_marginEnd="@dimen/_10sdp"
                        android:orientation="horizontal"
                        android:nestedScrollingEnabled="false"
                        android:layout_marginBottom="@dimen/_20sdp"
                        app:layout_behavior="@string/appbar_scrolling_view_behavior"
                        app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"

                        />
                </LinearLayout>



                <TextView
                    android:id="@+id/notfound"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_marginStart="@dimen/_15sdp"
                    android:layout_marginTop="@dimen/_20sdp"
                    android:layout_marginBottom="@dimen/_20sdp"
                    android:fontFamily="@font/lexend_semibold"
                    android:text="@string/DISPLAY_LIGHTS"
                    android:gravity="center"
                    android:visibility="gone"
                    android:textColor="?attr/hintTextColors"
                    android:textSize="@dimen/_12ssp" />
                <TextView
                    android:id="@+id/recommendTitle"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_above="@+id/addDeviceLayout"
                    android:layout_below="@+id/recyclerviewobj"
                    android:layout_marginStart="@dimen/_16sdp"
                    android:layout_marginTop="@dimen/_7sdp"
                    android:fontFamily="@font/lexend_semibold"
                    android:text="@string/RECOMMENDATION"
                    android:textColor="@color/gray_scale_placehold"
                    android:textSize="@dimen/_16ssp" />

                <LinearLayout
                    android:id="@+id/addDeviceLayout"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_above="@+id/createRoomLayout"
                    android:layout_marginTop="@dimen/_14sdp"
                    android:background="?attr/buttonTextColor"
                    android:orientation="vertical"
                    tools:visibility="visible">

                    <ImageView
                        android:id="@+id/addBtn"
                        android:layout_width="@dimen/_28sdp"
                        android:layout_height="@dimen/_28sdp"
                        android:layout_marginStart="@dimen/_16sdp"
                        android:layout_marginTop="@dimen/_8sdp"
                        android:src="@drawable/ic_thermostates_icon"
                        app:tint="?attr/colorPrimaryDark" />

                    <TextView
                        android:id="@+id/addDevice"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="@dimen/_16sdp"
                        android:layout_marginTop="@dimen/_5sdp"
                        android:fontFamily="@font/lexend_bold"
                        android:text="@string/PROGRAM_DISPLAY_SENSOR_PLUGS"
                        android:textColor="?attr/colorPrimaryDark"
                        android:textSize="@dimen/_12ssp" />

                    <TextView
                        android:id="@+id/summry"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="@dimen/_16sdp"
                        android:layout_marginTop="@dimen/_8sdp"
                        android:layout_marginBottom="@dimen/_6sdp"
                        android:fontFamily="@font/lexend_medium"
                        android:text="@string/DISPLAY_SENSOR_SUB_TITLE"
                        android:textColor="?attr/secondaryTextColor"
                        android:textSize="@dimen/_9ssp" />

                    <RelativeLayout
                        android:id="@+id/container3"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="@dimen/_6sdp"
                        android:layout_marginTop="@dimen/_6sdp"
                        android:layout_marginBottom="@dimen/_10sdp">

                        <TextView
                            android:id="@+id/get_started"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_centerVertical="true"
                            android:layout_marginStart="@dimen/_10sdp"
                            android:fontFamily="@font/lexend_semibold"
                            android:text="@string/RECOMMENDED_GROUP"
                            android:textAllCaps="true"
                            android:textSize="@dimen/_9ssp" />

                        <ImageView
                            android:id="@+id/forward_arrow"
                            android:layout_width="@dimen/_16sdp"
                            android:layout_height="@dimen/_16sdp"
                            android:layout_alignParentEnd="true"
                            android:layout_marginRight="@dimen/_20sdp"
                            android:src="@drawable/ic_forward_arrow"
                            app:tint="?attr/colorPrimary" />

                    </RelativeLayout>
                </LinearLayout>

                <LinearLayout
                    android:id="@+id/createRoomLayout"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_alignParentBottom="true"
                    android:layout_marginTop="@dimen/_9sdp"
                    android:layout_marginBottom="@dimen/_20sdp"
                    android:background="?attr/buttonTextColor"
                    android:orientation="vertical"
                    tools:visibility="visible">

                    <ImageView
                        android:id="@+id/addBtnRoom"
                        android:layout_width="@dimen/_28sdp"
                        android:layout_height="@dimen/_28sdp"
                        android:layout_marginStart="@dimen/_16sdp"
                        android:layout_marginTop="@dimen/_8sdp"
                        android:src="@drawable/rgb_light_new"
                        app:tint="?attr/colorPrimaryDark" />

                    <TextView
                        android:id="@+id/addRooms"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="@dimen/_16sdp"
                        android:layout_marginTop="@dimen/_5sdp"
                        android:fontFamily="@font/lexend_bold"
                        android:text="@string/DISPLAY_RGBW"
                        android:textColor="?attr/colorPrimaryDark"
                        android:textSize="@dimen/_12ssp" />

                    <TextView
                        android:id="@+id/summry1"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="@dimen/_16sdp"
                        android:layout_marginTop="@dimen/_8sdp"
                        android:layout_marginBottom="@dimen/_6sdp"
                        android:fontFamily="@font/lexend_medium"
                        android:text="@string/PROGRAM_DISPLAY_RGB_MSG"
                        android:textColor="?attr/secondaryTextColor"
                        android:textSize="@dimen/_9ssp" />

                    <RelativeLayout
                        android:id="@+id/container99"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="@dimen/_6sdp"
                        android:layout_marginTop="@dimen/_6sdp"
                        android:layout_marginBottom="@dimen/_10sdp">

                        <TextView
                            android:id="@+id/get_started_1"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_centerVertical="true"
                            android:layout_marginStart="@dimen/_10sdp"
                            android:fontFamily="@font/lexend_semibold"
                            android:text="@string/RECOMMENDED_GROUP"
                            android:textAllCaps="true"
                            android:textSize="@dimen/_9ssp" />

                        <ImageView
                            android:id="@+id/forward_arrow1"
                            android:layout_width="@dimen/_16sdp"
                            android:layout_height="@dimen/_16sdp"
                            android:layout_alignParentEnd="true"
                            android:layout_marginRight="@dimen/_20sdp"
                            android:src="@drawable/ic_forward_arrow"
                            app:tint="?attr/colorPrimary" />

                    </RelativeLayout>
                </LinearLayout>




            </LinearLayout>

        </androidx.core.widget.NestedScrollView>
    </LinearLayout>

</layout>

here use this property of recyclerview

app:layout_behavior="@string/appbar_scrolling_view_behavior"

and turned off recyclerview nested scrolling like this

android:nestedScrollingEnabled="false"
Gilolo answered 10/8, 2022 at 7:26 Comment(0)
F
1

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.

Flaccid answered 4/8, 2015 at 20:24 Comment(2)
Since RecyclerView implements NestedScrollingChild, RecyclerView should be able to be scrolled via NestedScrollView.Almagest
I just voted to reject 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.Assyriology
G
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>
Ghibelline answered 2/10, 2016 at 17:5 Comment(1)
But now it won't scroll above the RecyclerView...Vowel
H
1
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"/>
Hallerson answered 13/9, 2019 at 19:35 Comment(0)
A
1

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)

Ammo answered 23/11, 2020 at 15:7 Comment(2)
you can't use wrap_content with pagination, it will load all pages at once and height of recyclerview will be very big and it will eat a lot of cpu, memory and so onUnwished
@Unwished so what u suggest?Extraordinary
B
0

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>
Bodkin answered 2/7, 2020 at 13:38 Comment(1)
you can't use wrap_content with paginationUnwished
L
-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

Lecky answered 14/4, 2020 at 18:30 Comment(0)
S
-1

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.

Somber answered 29/11, 2020 at 2:9 Comment(0)
F
-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" />
Federalese answered 14/3, 2017 at 11:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.