RecyclerViews inside ScrollView is cutting off the last item - android

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.

Related

RecyclerView scroll get frezz/scroll slowly in NestedScrollView

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

RecyclerView content goes behind and not over TextView above

Consider this video from material design on drag & dropping items:
Material design reordering list
In the video you see a RecyclerView and above it a TextView with the text "Playlist". When the row is dragged up you see it going over the Playlist.
In my code the row goes behind the Textview. I've put RecyclerView's layout_height to match_parent. And I used a FrameLayout and placed the TextView below the RecyclerView. Why isn't it going over it?
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/layoutRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/txtTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="#dimen/general_margin"
android:text="#string/activity_bible_order_explanation"
android:layout_gravity="start|top" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
android:layout_marginTop="96dp"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</FrameLayout>
Use Constraint layout as a parent layout and add textview at the top by giving top constraints to the textview. then add
recyclerview's top constraint to the the bottom of textview and recyclerview bottom constraint to the bottom of parent then set height 0 it will work
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/layoutRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/txtTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
android:padding="#dimen/general_margin"
android:text="#string/activity_bible_order_explanation"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="#id/txtTitle"
android:background="#android:color/transparent"
android:layout_marginTop="96dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</androidx.constraintlayout.widget.ConstraintLayout>
Have you tried elevation? the problem might be that in the z axis the TextView is higher than the RecyclerView. try adding android:elevation="10dp" or higher... like this:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/layoutRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/txtTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="#dimen/general_margin"
android:text="#string/activity_bible_order_explanation"
android:layout_gravity="start|top" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:elevation="10dp" (if it doesn't work try maybe higher elevation, 20dp etc.)
android:background="#android:color/transparent"
android:layout_marginTop="96dp"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</FrameLayout>
Hope it works for you (: let me know!
What is the parent layout of this?
Because you set match_parent in recyclerview and list have many content that's why this issue facing.
Please give fix height or use relative layout and apply position above of text view in recyclerview
Problem with your layout code:
You're using a FrameLayout
Inside FrameLayout, you're also using top margin on your RecyclerView
android:layout_marginTop="96dp" <-- This causing the issue.
Solution:
You should LinearLayout instead of FrameLayout. And, also set LinearLayout's orientation as vertical.
android:orientation="vertical"
Also remove this line from your RecyclerView:-
android:layout_marginTop="96dp"
Solution Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/layoutRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/txtTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="Hello World"/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout>
The issue is not that the dragged view is going behind the TextView but, rather, the dragged view is not being drawn outside the bounds of the RecyclerView. The effect is the same.
To allow the RecyclerView to draw outside of itself, set the following for the parent of the RecyclerView:
android:clipChildren="false"
For the RecyclerView set
android:clipToPadding="false"
That should solve the problem.
The RecyclerView is above the text view in your FrameLayout. Currently, it appears that the underlying TextView is above the RecyclerView as you have given the background for the RecyclerView as:
android:background="#android:color/transparent"
To make this work as normal, either remove this line or change the background of RecyclerView to any value other than transparent.
There is 1 more issue. You need to place the recycler view first. Try this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/layoutRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
<TextView
android:id="#+id/txtTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="Hello World"/>
</LinearLayout>

RecyclerView inside another RecyclerView is not scrolling

My situation is simple. I have one RecyclerView and inside it is a few other RecyclerViews. The internal RecyclerViews do not scroll when I try to scroll them.
Why is this? Is there a workaround?
Root XML with root RecyclerView:
<?xml version="1.0" encoding="utf-8"?>
<com.boxed.v2.ui.category.SortAndFilterView android:id="#+id/sortfilterview"
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:layout_marginTop="?actionBarSize"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="vertical"
android:elevation="3dp"
app:contentViewId="#+id/content"
app:progressViewId="#+id/progressbar"
app:secondaryViewId="#+id/error">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:layout_marginTop="55dp"
android:paddingTop="10dp"
android:clickable="true"
android:orientation="vertical">
<TextView
android:id="#+id/textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/bright_teal"
android:text="Sort & Filters"
android:paddingLeft="12dp"
app:fontName="#string/font_sofia_medium"
android:textAllCaps="false"
android:textSize="24sp"
/>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="#+id/recycler_view"
android:background="#color/white"
android:orientation="vertical"
android:layout_margin="10dp"
></android.support.v7.widget.RecyclerView>
</LinearLayout>
</com.boxed.v2.ui.category.SortAndFilterView>
Then, nested item view containing nested RecyclerView (one of these per row in the root RecyclerView):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#drawable/textlines"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/text_view"
android:layout_width="match_parent"
android:height="55dp"
android:layout_height="wrap_content"
app:fontName="#string/font_sofia_medium"
android:textAllCaps="false"
android:gravity="center_vertical"
android:paddingLeft="5dp"
android:textSize="18sp" />
<LinearLayout
android:id="#+id/collapsable_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/embedded_recycler_view"
android:layout_width="match_parent"
android:layout_height="190dp"
android:background="#drawable/textlines"
></android.support.v7.widget.RecyclerView>
</LinearLayout>
</LinearLayout>
The LayoutManager gets Confused on which View to scroll,
To make the inner RV to scroll do this.
Create a NestedScrollView inside the Top RV
Then inside the NestedScrollView Put your second RV
NB
RV = recyvlerView
For a RecyclerView to scroll, one of two things must be true:
The RecyclerView has a smaller height than all of its items
The RecyclerView is inside a scrolling parent
In your case embedded_recycler_view height must be less then collapsable_content ( you have use match_parent and that is wrong) or you add another scrollview inside collapsable_content and then added embedded_recycle
then
set setHasFixedSize to true and also set setRecycledViewPool for child

My RecyclerView has many rows but shows only one row?

its recyclerview inside recyclerview inside recyclerview
it seems to be OK even the row is added but it doesn't show any thing.
many questions like this asked already and answered but none solved mine
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/fn_file_field_card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardElevation="0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="#dimen/fn_field_margin_right_and_left"
android:layout_marginTop="#dimen/fn_field_margin_top_or_bottom"
android:layout_marginRight="#dimen/fn_field_margin_right_and_left"
android:orientation="vertical">
<ir.tenthwindow.lbs.views.PersianTextView
android:id="#+id/fn_file_field_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="btn"
android:textColor="#color/black"
android:textSize="#dimen/fn_field_text_size"
android:textStyle="bold" />
<ir.tenthwindow.lbs.views.PersianTextView
android:id="#+id/fn_file_field_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/button_green"
android:gravity="center"
android:maxLines="1"
android:padding="10dp"
android:text="#string/upload_file"
android:textColor="#color/white"
android:textSize="#dimen/fn_field_text_size" />
<android.support.v7.widget.RecyclerView
android:id="#+id/fn_field_images_RecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="#dimen/fn_field_line_margin_top"
android:background="#color/fn_grey_line_border">
</View>
</LinearLayout>
</android.support.v7.widget.CardView>
Thx in advance for helping me
As mentioned, you need a layout manager for recyclerview to work. This can be added in xml, or programatically. In xml:
<android.support.v7.widget.RecyclerView
android:id="#+id/fn_field_images_RecyclerView"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
Or programatically:
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
yourRecyclerView.setLayoutManager(layoutManager);
Please note, there is also a GridLayoutManager if you want a grid layout.
Try to change height of recyclerview to match_parent instead of wrap_content.
<android.support.v7.widget.RecyclerView
android:id="#+id/fn_field_images_RecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
& height of layout in adapter to wrap_content if you set it as match_parent.
Also, set LinearLayoutManager to Vertical orientation.

RecyclerView inside ScrollView, some items are not shown

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>

Categories

Resources