Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RecyclerView does not Recycling Views when use it inside NestedScrollView

I'm using RecyclerView inside NestedScrollView. Also i set setNestedScrollingEnabled to false for recyclerview

to support lower API

ViewCompat.setNestedScrollingEnabled(mRecyclerView, false);

Now! When user scrolled the view every thing seems okay, but!!! views in recyclerview does not recycled!!! and Heap size grows swiftly!!

Update: RecyclerView layout manager is StaggeredLayoutManager

fragment_profile.xml:

<android.support.design.widget.CoordinatorLayout     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:id="@+id/coordinator"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:orientation="vertical" >          <android.support.design.widget.AppBarLayout             android:id="@+id/appbar"             android:layout_width="match_parent"             android:layout_height="wrap_content"             android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" >         </android.support.design.widget.AppBarLayout>          <android.support.v4.widget.SwipeRefreshLayout             android:id="@+id/profileSwipeRefreshLayout"             android:layout_width="match_parent"             android:layout_height="match_parent" >                  <!-- RecyclerView and NestedScrollView -->                 <include layout="@layout/fragment_profile_details" />          </android.support.v4.widget.SwipeRefreshLayout>  </android.support.design.widget.CoordinatorLayout> 

fragment_profile_details.xml:

<LinearLayout     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:id="@+id/rootLayout"     android:layout_width="match_parent"     android:layout_height="match_parent"     app:layout_behavior="@string/appbar_scrolling_view_behavior"     android:orientation="vertical" >          <android.support.v4.widget.NestedScrollView             android:id="@+id/nested_scrollbar"             android:layout_width="match_parent"             android:layout_height="match_parent"             android:layout_gravity="fill_vertical"             app:layout_behavior="@string/appbar_scrolling_view_behavior"             android:fillViewport="true"             android:scrollbars="none" >                  <LinearLayout                     android:id="@+id/nested_scrollbar_linear"                     android:layout_width="match_parent"                     android:layout_height="wrap_content"                     android:descendantFocusability="blocksDescendants"                     android:orientation="vertical" >                          <android.support.v7.widget.CardView                             android:id="@+id/profileCardview"                             android:layout_width="match_parent"                             android:layout_height="wrap_content"                             app:cardBackgroundColor="@color/card_backgroind"                             app:cardCornerRadius="0dp"                             app:cardElevation="0dp" >                              <!-- Profile related stuff like avatar and etc. --->                          </android.support.v7.widget.CardView>                          <android.support.v7.widget.RecyclerView                             android:id="@+id/list_view"                             android:layout_width="match_parent"                             android:layout_height="wrap_content"                             android:layout_marginBottom="@dimen/four"                             android:layout_marginEnd="@dimen/four"                             android:layout_marginLeft="@dimen/four"                             android:layout_marginRight="@dimen/four"                             android:layout_marginStart="@dimen/four"                             android:layout_marginTop="@dimen/four"                             app:layout_behavior="@string/appbar_scrolling_view_behavior"                             android:clipToPadding="false" />                  </LinearLayout>         </android.support.v4.widget.NestedScrollView> </LinearLayout> 

ProfileFragment.java:

mAdapter        = new MainAdapter(getActivity(), glide, Data);  listView        = (RecyclerView) view.findViewById(R.id.list_view);  ViewCompat.setNestedScrollingEnabled(listView, false);   listView.setAdapter(mAdapter);  mStaggeredLM    = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); mStaggeredLM.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);  listView.setLayoutManager(mStaggeredLM);  mScroll.setOnScrollChangeListener(new OnScrollChangeListener() {          @Override         public void onScrollChange(NestedScrollView arg0, int arg1, int arg2, int arg3, int arg4) {              View view   = (View) mScroll.getChildAt(mScroll.getChildCount() - 1);             int diff    = (view.getBottom() - ( mScroll.getHeight() + mScroll.getScrollY()));              if(diff == 0){                  int visibleItemCount            = mStaggeredLM.getChildCount();                 int totalItemCount              = mStaggeredLM.getItemCount();                  int[] lastVisibleItemPositions  = mStaggeredLM.findLastVisibleItemPositions(null);                 int lastVisibleItemPos  = getLastVisibleItem(lastVisibleItemPositions);                  Log.e("getChildCount", String.valueOf(visibleItemCount));                 Log.e("getItemCount", String.valueOf(totalItemCount));                 Log.e("lastVisibleItemPos", String.valueOf(lastVisibleItemPos));                  if ((visibleItemCount + 5) >= totalItemCount) {                      mLoadMore.setVisibility(View.VISIBLE);                     Log.e("LOG", "Last Item Reached!");                 }                  mMore = true;                 mFresh = false;                 mRefresh = false;                 getPosts();             }          }      }); 

P.s : I've set load more to scroll view, because recyclerview do it continuously and none stoppable!

Any help is appreciated

like image 245
MAY3AM Avatar asked Jun 02 '16 11:06

MAY3AM


People also ask

How does RecyclerView recycle?

RecyclerView does not allocate an item view for every item in your data source. Instead, it allocates only the number of item views that fit on the screen(Viewport) and it reuses those item layouts as the user scrolls.

Can we use RecyclerView inside RecyclerView in Android?

A nested RecyclerView is an implementation of a RecyclerView within a RecyclerView. An example of such a layout can be seen in a variety of apps such as the Play store where the outer (parent) RecyclerView is of Vertical orientation whereas the inner (child) RecyclerViews are of horizontal orientations.

What is nested scrolling in RecyclerView?

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.

Why we use nested scroll view?

NestedScrollView is used when there is a need for a scrolling view inside another scrolling view.


2 Answers

This is because we have a recycler view which has scroll behaviour inside a scroll view. (scroll inside a scroll)

I think the best way to resolve this issue is to your profileCardview as a header in your recycler view and then remove the nested scroll view.

If it were a listview then it was as simple as listView.addHeaderView(profileCardView) but for the Recycler view there is no addheadview equivalent. Hence you could refer the below link to change your implementation.

Is there an addHeaderView equivalent for RecyclerView?

like image 57
Arpit Ratan Avatar answered Sep 24 '22 19:09

Arpit Ratan


For a RecyclerView or ListView the height should be constant, because if it will not a constant size then how it will manage the maximum number of visible rows in memory. Try by changing RecyclerView attribute android:layout_height="match_parent" or a fixed height(e.g. "300dp" - as needed), instead of "wrap_content". It should improve your memory management.

like image 27
Neo Avatar answered Sep 24 '22 19:09

Neo