web-dev-qa-db-fra.com

RecyclerView ne recycle pas les vues lors de son utilisation dans NestedScrollView

J'utilise RecyclerView dans NestedScrollView. J'ai également défini setNestedScrollingEnabled sur false pour recyclerview

pour prendre en charge une API inférieure

ViewCompat.setNestedScrollingEnabled(mRecyclerView, false);

À présent! Lorsque l'utilisateur fait défiler la vue, tout semble correct, mais !!! vues dans recyclerview ne recycle pas !!! et la taille du tas augmente rapidement !!

Mise à jour: le gestionnaire de disposition de RecyclerView est 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: J'ai configuré load more pour faire défiler la vue, car recyclerview le fait en continu et sans arrêt!

Toute aide est appréciée

54
MAY3AM

C'est parce que nous avons une vue de recycleur qui a un comportement de défilement dans une vue de défilement. (faites défiler à l'intérieur d'un parchemin)

Je pense que la meilleure façon de résoudre ce problème est de créer votre profileCardview en tant qu'en-tête dans votre vue de recycleur, puis de supprimer la vue de défilement imbriquée.

S'il s'agissait d'une liste, alors c'était aussi simple que listView.addHeaderView (profileCardView), mais pour la vue Recycler, il n'y a pas d'équivalent addheadview. Par conséquent, vous pouvez vous référer au lien ci-dessous pour modifier votre implémentation.

Existe-t-il un équivalent addHeaderView pour RecyclerView?

8
Arpit Ratan

Pour un RecyclerView ou ListView, la hauteur doit être constante, car si ce n'est pas une taille constante, alors comment il va gérer le nombre maximal de lignes visibles en mémoire. Essayez en modifiant l'attribut RecyclerView Android:layout_height="match_parent" au lieu de "wrap_content". Cela devrait améliorer la gestion de votre mémoire.

2
Neo