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
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.
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.
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.
NestedScrollView is used when there is a need for a scrolling view inside another scrolling view.
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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With