I am trying to create a scroll-able area which will contain various sections of the following types:
Horizontal Recycling Section
Vertical Recycling Section
Text Section
The approach I am taking is to have a NestedRecyclerView
as the parent scroll view for all the child sections. This view looks like so:
<?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">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/mynav_appbarLayout"
android:background="?attr/themeToolbarBg"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="@+id/mynav_toolbar"
layout="@layout/actionbar_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<LinearLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"/>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
Then, for each section type I am creating a corresponding view binding and adding it as a child to the LinearLayout
which is inside the NestedScrollView
.
There are 2 types of section layout, one which is a simple TextView
(which I will omit here as it is not relevant) the other of which is a view which contains a RecyclerView
. The layout manager for this RecyclerView
is created dynamically depending on whether the section it is to be used for is a horizontal or vertical section.
The layout with the RecyclerView
in looks like so:
<?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">
<LinearLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:focusable="true"
android:focusableInTouchMode="true">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/fooBarsRecycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:nestedScrollingEnabled="false"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"/>
</LinearLayout>
</layout>
Now, when I am adding these views to the parent NestedScrollView
's LinearLayout
and setting up the LayoutManager
for the associated RecyclerView
to orientation Horizontal
it works fine, but, when I use orientation Vertical
(which is the same orientation as the NestedScrollView
) the RecyclerView
is NOT recycling views. Obviously this is leading to unacceptable performance.
After doing about a days worth of research and banging my head against the wall it appears that having a RecyclerView
nested within a NestedScrollView
with the same orientation as the NestedScrollView
causes the RecyclerView
to lose it's recycler functionality.
As you can hopefully see from the above layout, I have tried all the suggestions I could find, making sure the RecyclerView
's height is not wrap_content
, using layout_behaviour
, setting the NestedRecyclerView
to fill view port and so on.
I have exhausted 6 pages of google search around this issue and have tried every suggestion I have found either on SO or blogs and nothing is working.
Oddly, if I swap out the NestedScrollView
for a ScrollView
, the vertical RecyclerView
regains it's recycler functionality, but now scrolls independently of the parent ScrollView
which doesn't meet our requirements.
Is this a solved problem or do I need to rethink my entire solution? I.e. am I just missing an attribute or doing something wrong in the XML or is it fundamentally an issue with using a RecyclerView
inside a NestedScrollView
with the same orientation?
Here is the list of resources, the suggestions of which I have tried exhaustively to no avail:
How to use RecyclerView inside NestedScrollView?
How to use RecyclerView inside NestedScrollView
Recycler view inside NestedScrollView causes scroll to start in the middle
https://android.jlelse.eu/recyclerview-within-nestedscrollview-scrolling-issue-3180b5ad2542
https://github.com/google/flexbox-layout/issues/400
https://github.com/mikepenz/FastAdapter/issues/447
https://www.reddit.com/r/androiddev/comments/bixl6r/nestedscrollview_recyclerview/
View Recycling not happens with Multiple Recyclerview inside NestedScrollView
How to make RecyclerView do recycling inside NestedScrollView?
https://code-examples.net/en/q/1d90611
As per a suggestion in the comments, I could model this with a multi type adapter, which is something I have done before but for this particular problem I am not sure this approach will work.
I think the comment is suggesting I model it like so:
Where the adapter would adapt types:
- Horizontal Section
- Text Section
- Card Section
But, the requirement is this:
So, as you can hopefully see, the RecyclerView
will have a LinearLayoutManager
with orientation Vertical, but, once we hit the cards, they have to be laid out in a grid fashion, which of course the LinearLayoutManager
does not support. So, perhaps I can have the final section be another RecyclerView
with a GridLayoutManager
? But, I tried this last night and it didn't work, there were scrolling issues as the bottom most RecyclerView
is scrolling vertically within the outermost RecyclerView
which is also scrolling vertically.