I have NestedScrollView. In NestedScrollView contains two RecyclerView that both scroll vertically.
when first RecyclerView list scrolling end/stop then second RecyclerView list stared scrolling.
While at first time when scrolling is started screen getting freeze/ scroll slowly . After sometime smoothly scrolling happen.
Why first Time of Scrolling screen getting freeze? How to avoid screen freeze/scroll slowly?
Because of NestedScrollView, Without scrolling continuously onScrollMethod and EndlessRecyclerViewScrollListener(Used for pagination)get called.How to avoid getting call of EndlessRecyclerViewScrollListener method.
I am adding my layout code. waiting for answer.
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
android:gravity="center"
android:text="First List" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvFirstList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="#dimen/dimen_4" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
android:gravity="center"
android:text="Secound List" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/secoundRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="#dimen/dimen_4" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
Firstly, your view hierarchy doesn't seem right.
Your start tags are:
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
<androidx.core.widget.NestedScrollView
<LinearLayout
And your closing tags aren't matching
</androidx.core.widget.NestedScrollView>
</LinearLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
Swap NestedScrollView with LinearLayout at the end.
Then try adding this:
app:layout_behavior="#string/appbar_scrolling_view_behavior"
To your <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
block
try
recyclerView.setNestedScrollingEnabled(false)
on both of your recyclerViews
Related
I have a RecyclerView inside a HorizontalScrollView. I don't see inside RecyclerView all the items. I have looked and even if the list in the adapter has 7 items, onBindViewHolder is called only 4 times! If I take out the HorizontalScrollView, it works ok.
I use the HorizontalScrollView because I need to scroll the list with the background of the recycle, not inside recycle, how it usually works.
So, I need a solution to scroll a list with the background of the list, or to show all the items using HorizontalScrollView
UPDATE :
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="20dp">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:scrollbars="none"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/label">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/rlWrapper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="#id/paddingStartView"
android:background="#drawable/bg_round_corner">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/optionsRv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintStart_toStartOf="parent" />
</RelativeLayout>
<View
android:id="#+id/paddingStartView"
android:layout_width="16dp"
android:layout_height="16dp" />
<View
android:id="#+id/paddingEndView"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_toEndOf="#id/rlWrapper" />
</RelativeLayout>
</HorizontalScrollView>
<TextView
android:id="#+id/label"
style="#style/FontLocalizedMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:textAllCaps="true"
android:textColor="#979797"
android:textSize="12sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Tempareature" />
</androidx.constraintlayout.widget.ConstraintLayout>
Make the child of the HorizontalScrollView to be RelativeLayout instead of LinearLayout
I just ran into this too, and the accepted answer helped. I had:
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="none"
android:fillViewport="true">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/dates_recycler"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</HorizontalScrollView>
and it didn't show all the items in the horizontally-oriented recycler view. It only showed enough items that would fit in the width of the device view, call onBindViewHolder that many times, etc. Adding a RelativeLayout in between the HorizontalScrollView and the RecyclerView fixed it, so that it showed all the items whether they fit all in the width of the device, or not, and you could scroll to reach them.
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="none"
android:fillViewport="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/dates_recycler"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</androidx.recyclerview.widget.RecyclerView>
</RelativeLayout>
</HorizontalScrollView>
I think also setting the android:layout_width="match_parent" to the RelativeLayout is key.
onBindViewHolder is only called for the "visible on screen" items. If total item is 7 and the screen can only show 4, then everything is ok.
Hence the name "RecycleView", it recycles visible views, there are onle 4 views in total in your RecycleView
This I dont understand what you mean!?
I use the HorizontalScrollView because I need to scroll the list with
the background from recycle, not inside recycle, how it usually works.
So, I need a solution to scroll a list with the background of the
list, or to show all the items using HorizontalScrollView
I have a RecyclerView with a fixed height inside a NestedScrollView with a few other layouts inside it. The recycler view won't scroll, but it scrolls fine if I set its height to wrap_content.
I cannot make the RecyclerView use wrap_content because there is an issue with EndlessRecyclerViewScrollListener that it keeps loading data from the server and pushing it into my Adapter even if the user has not scrolled down at all.
Most are suggesting to set nested scrolling to false, but if I disable nested scrolling, the NestedScrollView does not allow me to scroll my RecyclerView. But if I leave nested scrolling enabled, the scroll view does not scroll unless I start touching from outside the RecyclerView.
My layout code:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/scoop_background"
tools:context=".module.scoop.timeline.ScoopTimelineFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="92dp">
<ImageView
android:id="#+id/ivTimelineBanner"
android:layout_width="match_parent"
android:layout_height="92dp"
android:layout_margin="0dp"
android:clickable="true"
android:padding="0dp"
android:scaleType="fitXY"
android:src="#drawable/banner_placeholder" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingLeft="92dp">
<TextView
android:id="#+id/tvGroupMembership"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:textSize="#dimen/text_content" />
<TextView
android:id="#+id/tvGroupName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:textSize="#dimen/text_header"
android:textStyle="bold" />
<TextView
android:id="#+id/tvGroupMemberCount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:textSize="#dimen/text_content" />
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="#null"
android:paddingStart="#dimen/divider_normal"
android:paddingEnd="#dimen/divider_normal"
android:src="#drawable/ic_chevron_right_white_24dp" />
</LinearLayout>
</FrameLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipeRefreshLayoutTimeline"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.NestedScrollView
android:id="#+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:overScrollMode="never"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="4dp">
<android.support.v7.widget.CardView
android:id="#+id/cvCreateScoop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/divider_small"
android:layout_marginRight="#dimen/divider_small"
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground"
app:cardCornerRadius="8dp"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="#dimen/divider_normal">
<ImageView
android:layout_width="32dp"
android:layout_height="32dp"
android:src="#drawable/svg_nav_create_scoop" />
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
android:paddingStart="#dimen/divider_normal"
android:text="What's on your mind?"
android:textSize="#dimen/text_content" />
<ImageView
android:layout_width="32dp"
android:layout_height="32dp"
android:padding="#dimen/divider_xsmall"
android:src="#drawable/svg_insert_image" />
</LinearLayout>
</android.support.v7.widget.CardView>
<RelativeLayout
android:id="#+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:overScrollMode="never"
android:nestedScrollingEnabled="false"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:paddingBottom="4dp">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
What do I have to modify so that the RecyclerView is scrollable, but the whole NestedScrollView also scrolls along with it, so that if the user is scrolling back up (swiping from top to bottom), the RecyclerView will scroll along with the NestedScrollView, which will bring the layouts above RecyclerView.
To visualize:
The layout I'm trying to achieve is similar to that of facebook's. When you scroll down, the timeline will scroll down, and the search bar with the messenger icon at the top is also scrolled so that it is hidden when scrolling down. When you scroll up, the timeline is being scrolled back up, and showing the search bar again.
I decided to do it differently because I wasn't able to solve it with this method. Instead, I used a CollapsingToolbar and put the other layouts inside it, then removing its background so it does not look like a toolbar, and it seamlessly does what I wanted to, just with a different implementation.
I have a ScrollView with a LinearLayout, and several different RecyclerView inside because I load data from different sources.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/posts_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:clipToPadding="false"
android:padding="10dp"
android:layout_marginTop="20dp"
android:nestedScrollingEnabled="false"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/movies_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:clipToPadding="false"
android:padding="10dp"
android:layout_marginTop="20dp"
android:nestedScrollingEnabled="false"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/tv_shows_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:clipToPadding="false"
android:padding="10dp"
android:layout_marginTop="20dp"
android:nestedScrollingEnabled="false"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/music_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:clipToPadding="false"
android:padding="10dp"
android:layout_marginTop="20dp"
android:nestedScrollingEnabled="false"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/books_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:clipToPadding="false"
android:padding="10dp"
android:layout_marginTop="20dp"
android:nestedScrollingEnabled="false"/>
</LinearLayout>
I use both LinearLayoutManager and GridLayoutManager to organise the content showed by the recyclerviews.
GridLayoutManager layoutManager = new GridLayoutManager(context, 2);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
For some reason, the last element of the second RecycleView (with a GridLayout) is getting cut off.
While elements of the other RecycleViews are showed in the correct way.
I don't know if it is important, but inside the RecycleViews I use CardViews.
Any help would be greatly appreciated since I am going nuts with this problem :(
SOLUTION
The solution is simple: I just used NestedScrollView instead of ScrollView and it works fine.
Use the Nested Scroll View instead of Scroll View in this situation.
putting a bottom margin on linear layout will solve your problem.The bottom margin should be the height size of recycler view row.
I had a RecyclerView in ScrollView like this:
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--other stuff-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"/>
</LinearLayout>
<!--other stuff-->
</ScrollView>
And the RecyclerView's item is a RelativeLayout, inside of which there is an EditText and other views. The layout_height of that RelativeLayout and EditText is both wrap_content. User can input into that EditText without any limit of length/lines so that each item's height is different.
Then I found that getItemCount() in Adapter returns true value but onBindViewHolder() is called of wrong times(less than it should be), thus not enough to show all items.
I found that this will happen only if I wrote recyclerView.setNestedScrollingEnabled(false). But I cannot remove this line. Because if I did so, the RecyclerView won't scroll smoothly and is not harmonious with other views inside ScrollView and ScrollView itself.
This occurs on 6.0 but not on 4.1.
I communicated with Google at this page: https://code.google.com/p/android/issues/detail?id=213914 and he told me this is a bug fix for RecyclerView. You can visit that page so that you can understand the question and my goal better(There is a small sample project to show the problem there). I don't agree with him even now and I want to solve the problem. Please help, thank you in advance.
I found the solution myself: replace ScrollView with NestedScrollView and keep recyclerView.setNestedScrollingEnabled(false). I don't know if this is what NestedScrollView is made for but it works.
NOTICE:
NestedScrollView is not a child of ScrollView but of FrameLayout.
This solution will also bring some bugs with self-simulated adjustResize.
In my case, I replaced LineaLayout with RelativeLayout and it's solved the issue and all items have shown.
The answer is:
androidx.core.widget.NestedScrollView
In the first step, you need to create NestedScrollView element in XML:
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
// RecyclerViews should be located here
</LinearLayout>
</androidx.core.widget.NestedScrollView>
Next, add the below attribute to recyclerView:
android:overScrollMode="never"
Then, the recyclerView will be as following:
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never" />
Finally, the whole the layout will be something like below, you can add other materials inside LinearLayout:
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never" />
// other materials
</LinearLayout>
</androidx.core.widget.NestedScrollView>
Celebrate.............;)
The best solution is to keep multiple Views in a Single View / View Group and then keep that one view in the SrcollView. ie.
Format -
<ScrollView>
<Another View>
<RecyclerView>
<TextView>
<And Other Views>
</Another View>
</ScrollView>
Eg.
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="any text"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:text="any text"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</ScrollView>
Another Eg. of ScrollView with multiple Views
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:layout_weight="1">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="10dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/CategoryItem"
android:textSize="20sp"
android:textColor="#000000"
/>
<TextView
android:textColor="#000000"
android:text="₹1000"
android:textSize="18sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:textColor="#000000"
android:text="so\nugh\nos\nghs\nrgh\n
sghs\noug\nhro\nghreo\nhgor\ngheroh\ngr\neoh\n
og\nhrf\ndhog\n
so\nugh\nos\nghs\nrgh\nsghs\noug\nhro\n
ghreo\nhgor\ngheroh\ngr\neoh\nog\nhrf\ndhog"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
I'm trying to put a RecyclerView, inside a ScrollView. But the ScrollView doesn't scrolls and the RecyclerView does but I don't want it to... What can I do?
I tried with this class https://stackoverflow.com/a/30222721/4864104 and in fact the RecyclerView doesn't scroll anymore, but neither does the ScrollView.
Any help to make the ScrollView work even with the disabled RecyclerView? Thanks in advance.
This is my layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fab="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="jahirfiquitiva.projects.activities.DeveloperActivity">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar" />
<ScrollView
android:id="#+id/osv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/toolbar"
android:fillViewport="true"
android:gravity="center"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dp">
<ImageView
android:id="#+id/photoJahir"
android:layout_width="144dp"
android:layout_height="144dp"
android:layout_gravity="center"
android:gravity="center" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineSpacingMultiplier="1.2"
android:paddingBottom="#dimen/lists_padding"
android:paddingTop="#dimen/lists_padding"
android:text="#string/developer_bio"
android:textSize="#dimen/abc_text_size_subtitle_material_toolbar" />
<View
android:layout_width="match_parent"
android:layout_height="#dimen/dividers_about_section"
android:alpha="0.3"
android:background="#color/primary" />
<RecyclerView
android:id="#+id/buttonsGrid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/lists_padding"
android:paddingTop="#dimen/lists_padding" />
<View
android:layout_width="match_parent"
android:layout_height="#dimen/dividers_about_section"
android:alpha="0.3"
android:background="#color/primary" />
<View
android:layout_width="match_parent"
android:layout_height="72dp" />
</LinearLayout>
</ScrollView>
You could easily achieve it by changing your scroll view into a NestedScrollView and setting recyclerView.setNestedScrollingEnabled(false)
Has the highest performance and No need to override the layout manager.
I think you just need to wrap recyclerView so that other views can be visible. Just use this library so that you can adjust recycler view height coz linearLayoutManager as per now matches height to match parent.
https://github.com/serso/android-linear-layout-manager
it not as simple as you think. when you use tow scrollble element inside each other you are in hot water! you should calculate the Recycler item height and then find the whole recycler height.
look at below link, I explain completely this problem.
Use RecyclerView indie ScrollView with flexible recycler item height
I hope it help you