I have used Recycler View Inside Nested Scroll View(which is within CoordinatorLayout):
<android.support.v4.widget.NestedScrollView
android:id="#+id/scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/sections_recycler_view_linearlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" />
</RelativeLayout>
</android.support.v4.widget.NestedScrollView>
Within the adapter of above recycler I have added Child Recycler Views programatically using setNestedScrollingEnabled as false.
My Issue is:
When I am scrolling the child recycler, as soon as its scroll is completed the parent recycler scrolls to top, as if I am setting its adapter again. I have not added any code to notify adapter or to scroll to top-most recycler item or to set adapter again. I could not figure out the reason for this strange behavior.
Any help would be highly appreciated.. !!!
Add to your parent Recycler View:
android:descendantFocusability="blocksDescendants"
I was display progress bar in child recycler views until I receive data from server. And once I get data I was populating it. I had used staggered Adapter for child recyclers with row count 2 and hence after data got populated my parent recyler's height was changing.
I used setHasFixedSize(false) for parent recycler view as its height was changing and I have not seen the issue again till now.
Easy,
Add
android:fillViewport="true"
to your NestedScrollview and you will be good to go.
Related
How to trigger a recyclerview scroll listener when it is inside a scroll view?
Here the scroll view listener is alone triggering
1. Set nested scrolling enabled false of recycler view.
recyclerView.setNestedScrollingEnabled(false);
2. Add scroll listner to nested scrollview.
mScrollView.getViewTreeObserver().addOnScrollChangedListener(new
ViewTreeObserver.OnScrollChangedListener() {
#Override
public void onScrollChanged()
{
View view = (View)mScrollView.getChildAt(mScrollView.getChildCount() - 1);
int diff = (view.getBottom() - (mScrollView.getHeight() + mScrollView
.getScrollY()));
if (diff == 0) {
// your pagination code
}
}
});
Try with NestedScrollView instead of ScrollView.
NestedScrollView is just like ScrollView, but it supports acting as both a nested scrolling parent and child on both new and old versions of Android. Nested scrolling is enabled by default.
Note: You have to set setNestedScrollingEnable(false) to your recylerview.
in xml add android:nestedScrollingEnabled="false" in recyclerview
OR
programmatically yourRecylerview.setNestedScrollingEnabled(false);
See this article.
You can try this one, but still I assuming you may have the same code like mine as you didnot post your needed code into your question.
Try this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.widget.NestedScrollView
android:id="#+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</LinearLayout>
Use NestedScrollView with <android.support.v7.widget.RecyclerView as I have mention above.
Its ScrollListener will not work as all the rows gets layed when recyclerview is inside scrollview whole purpose of recyclerview gets destroyed when you put it inside scroll view.
For Example as the recyclerview will stretch to full fill its parent ,when you will put it inside scroll view , in case of scroll view it will stretch to its fullest. if there are 1000 items in recyclerview all it will draw 1000 different rows which is also a performance issue.
You should remove it from a scroll view to make its scroll listener working
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://medium.com/#mujtahidah/load-more-recyclerview-inside-nested-scroll-view-and-coordinator-layout-4f179dc01fd
https://github.com/google/flexbox-layout/issues/400
https://www.reddit.com/r/androiddev/comments/8oj8cb/having_recyclerview_inside_a_nestedscrollview_is/
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.
I have a RecyclerView inside a NestedScrollView:
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="#dimen/_100sdp">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view_chat"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="#dimen/_100sdp"
android:layout_marginLeft="#dimen/_30sdp"
android:layout_marginRight="#dimen/_30sdp"
android:background="#color/bright_grey"
></android.support.v7.widget.RecyclerView>
</android.support.v4.widget.NestedScrollView>
My RecyclerView is being filled with items in onCreate()
On a device you would see the first item of the RecyclerView on the very top und would have to scroll down the NestedScrollView in order to see the last item.
Since my items are chat message sorted by the time sent I need the NestedScrollView to be scrolled all the way down so users would see the latest chat message first without having to scroll in the first place.
Any ideas on this?
Given that your RecyclerView is the only child of your NestedScrollView, you would be better off removing the NestedScrollView altogether, and instead applying the fixed height to the RecyclerView. Something like this:
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view_chat"
android:layout_width="match_parent"
android:layout_height="#dimen/_100sdp"
android:layout_marginLeft="#dimen/_30sdp"
android:layout_marginRight="#dimen/_30sdp"
android:background="#color/bright_grey" />
Doing this allows you to have the RecyclerView itself manage scrolling, rather than the parent scroll view. And that allows you to leverage a property of LinearLayoutManager to achieve what you want.
Reverse layout -- setting this will "invert" your list; the first item in your adapter will appear at the bottom of the list, and the default scroll position of the RecyclerView will be to scroll all the way to the bottom.
https://developer.android.com/reference/android/support/v7/widget/LinearLayoutManager.html#setReverseLayout(boolean)
LinearLayoutManager lm = new LinearLayoutManager(this);
lm.setReverseLayout(true);
If you have the same issue and want to keep the NestedScrollView.
It will work like this.
Handler(Looper.getMainLooper()).postDelayed({
binding.nestedScrollView.smoothScrollTo(
0,
binding.recyclerview.measuredHeight,
500
)
// binding.nestedScrollView.scrollTo(0, binding.recyclerview.measuredHeight)
// binding.nestedScrollView.smoothScrollTo(0, binding.recyclerview.measuredHeight)
}, 50L)
For me, it didn't work without delay.
I want to create multiple list view inside ScrollView in Android. I have created the two list view inside ScrollView. In first List View each row contains a single text upto 5 rows will be presented. Whereas, in second list view each row will contains multiple paragraph text, ie, text very long . In my case I am unable to scroll the second list to view fully.
Is any other way available to handle this scenario ?
Its Work in My RecyclerView try this:
<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>
You need to disable nested scrolling programatically. It doesn't seem to work correctly if done in xml.
recyclerView.setNestedScrollingEnabled(false);
Don't use the listview inside the scroll view, the listview is already scrollable . Using a ListView to make it not scroll is extremely expensive and goes against the whole purpose of ListView. You should NOT do this. Just use a LinearLayout instead.
I am using a LinearLayout with some views inside. The second last is a RecyclerView, and the last one is an <include> tag linked with a RelativeLayout. I want the last view to be visible permanently, as I want to use it to add items to the RecyclerView.
My problem is that the <include> view below the RecyclerView disappears whenever the adapter is empty. Is there any way to avoid this behaviour?
EDIT
There is a constraint in the way I want the RecyclerView and the "add" View to work together. I would like that it feels as the "add" view is always the last item in the RecyclerView, as it happens in Google Keep lists.
Example Google Keep list example (I cannot add images yet)
You could try to replace your LinearLayout with a RelativeLayout; then you anchor the bottom view to the bottom of the screen, and the RecyclerView would be set above that view. Something like this (just a skeleton):
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent>
<-! other views here -->
<include layout="#layout/something"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:id="#bottomView" />
<RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/some_view_above_recyclerview"
android:layout_above="#+id/bottomView" />
</RelativeLayout>