Comment utiliser RecyclerView dans NestedScrollView?

Comment utiliser RecyclerView dans NestedScrollView ? RecyclerView contenu RecyclerView n’est pas visible après la configuration de l’adaptateur.

Mise à jour du code de mise à jour

         

Remplacez votre recyclerView par,

  

ici,

 app:layout_behavior="@ssortingng/appbar_scrolling_view_behavior" 

va gérer le rest des choses.

Encore une chose, pas besoin de mettre votre recyclerView à l’intérieur de NestedScrollView

METTRE À JOUR

Depuis Android Support Library 23.2.0, la méthode setAutoMeasureEnabled(true) pour LayoutManagers a été ajoutée. Cela rend RecyclerView pour envelopper son contenu et fonctionne comme un charme.
http://android-developers.blogspot.ru/2016/02/android-support-library-232.html

Donc, ajoutez simplement quelque chose comme ceci:

  LayoutManager layoutManager = new LinearLayoutManager(this); layoutManager.setAutoMeasureEnabled(true); recyclerView.setLayoutManager(layoutManager); recyclerView.setNestedScrollingEnabled(false); 

Ancienne réponse (non recommandé)

Vous pouvez utiliser RecyclerView dans NestedScrollView . Tout d’abord, vous devez implémenter votre propre LinearLayoutManager personnalisé, cela rend votre RecyclerView pour envelopper son contenu. Par exemple:

 public class WrappingLinearLayoutManager extends LinearLayoutManager { public WrappingLinearLayoutManager(Context context) { super(context); } private int[] mMeasuredDimension = new int[2]; @Override public boolean canScrollVertically() { return false; } @Override public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) { final int widthMode = View.MeasureSpec.getMode(widthSpec); final int heightMode = View.MeasureSpec.getMode(heightSpec); final int widthSize = View.MeasureSpec.getSize(widthSpec); final int heightSize = View.MeasureSpec.getSize(heightSpec); int width = 0; int height = 0; for (int i = 0; i < getItemCount(); i++) { if (getOrientation() == HORIZONTAL) { measureScrapChild(recycler, i, View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), heightSpec, mMeasuredDimension); width = width + mMeasuredDimension[0]; if (i == 0) { height = mMeasuredDimension[1]; } } else { measureScrapChild(recycler, i, widthSpec, View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), mMeasuredDimension); height = height + mMeasuredDimension[1]; if (i == 0) { width = mMeasuredDimension[0]; } } } switch (widthMode) { case View.MeasureSpec.EXACTLY: width = widthSize; case View.MeasureSpec.AT_MOST: case View.MeasureSpec.UNSPECIFIED: } switch (heightMode) { case View.MeasureSpec.EXACTLY: height = heightSize; case View.MeasureSpec.AT_MOST: case View.MeasureSpec.UNSPECIFIED: } setMeasuredDimension(width, height); } private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec, int heightSpec, int[] measuredDimension) { View view = recycler.getViewForPosition(position); if (view.getVisibility() == View.GONE) { measuredDimension[0] = 0; measuredDimension[1] = 0; return; } // For adding Item Decor Insets to view super.measureChildWithMargins(view, 0, 0); RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams(); int childWidthSpec = ViewGroup.getChildMeasureSpec( widthSpec, getPaddingLeft() + getPaddingRight() + getDecoratedLeft(view) + getDecoratedRight(view), p.width); int childHeightSpec = ViewGroup.getChildMeasureSpec( heightSpec, getPaddingTop() + getPaddingBottom() + getDecoratedTop(view) + getDecoratedBottom(view), p.height); view.measure(childWidthSpec, childHeightSpec); // Get decorated measurements measuredDimension[0] = getDecoratedMeasuredWidth(view) + p.leftMargin + p.rightMargin; measuredDimension[1] = getDecoratedMeasuredHeight(view) + p.bottomMargin + p.topMargin; recycler.recycleView(view); } } 

Après cela, utilisez ce LayoutManager pour votre RecyclerView

 recyclerView.setLayoutManager(new WrappingLinearLayoutManager(getContext())); 

Mais vous devriez aussi appeler ces deux méthodes:

 recyclerView.setNestedScrollingEnabled(false); recyclerView.setHasFixedSize(false); 

Ici, setNestedScrollingEnabled(false) désactive le défilement pour RecyclerView . Par conséquent, il n'intercepte pas l'événement de défilement de NestedScrollView . Et setHasFixedSize(false) détermine que les modifications du contenu de l’adaptateur peuvent modifier la taille de RecyclerView

Remarque importante: cette solution est peu bugée dans certains cas et présente des problèmes de performances, donc si vous avez beaucoup d’éléments dans RecyclerView je vous recommande d’utiliser une implémentation de liste personnalisée LinearLayout sur LinearLayout , de créer un adaptateur pour cela et le faire se comporter comme ListView ou RecyclerView

1) Vous devez utiliser la bibliothèque de support 23.2.0 (ou) ci-dessus

2) et la hauteur RecyclerView sera wrap_content .

3) recyclerView.setNestedScrollingEnabled(false)

Mais ce faisant, le modèle de recyclage ne fonctionne pas. (c.-à-d. que toutes les vues seront chargées en une fois parce que wrap_content besoin de la hauteur de RecyclerView complète pour dessiner toutes les View enfant en même temps. Aucune vue ne sera recyclée). Essayez de ne pas utiliser ce modèle util sauf si c’est vraiment nécessaire. Essayez d’utiliser viewType et ajoutez toutes les autres vues qui doivent défiler à RecyclerView plutôt que d’utiliser RecyclerView dans la Scrollview de Scrollview . L’impact sur la performance sera très élevé.

Pour simplifier, “il agit simplement comme LinearLayout avec toutes les vues enfants”

Vous pouvez utiliser android:fillViewport="true" pour que NestedScrollView mesure le RecyclerView . Le RecyclerView remplira la hauteur restante. Donc, si vous voulez faire défiler le NestScrollView , vous pouvez définir le minHeight RecyclerView .

Il suffit d’append recyclerView.setNestedScrollingEnabled(false); avant que setAdapter lui-même ne fonctionne pour moi. Je n’ai pas ajouté app:layout_behavior="@ssortingng/appbar_scrolling_view_behavior" n’importe où et n’a pas défini de gestionnaire de disposition personnalisé

             

C’est ce qui marche pour moi

    

Essayez d’utiliser cette bibliothèque – https://github.com/serso/android-linear-layout-manager .

LayoutManager de la bibliothèque fait que RecyclerView encapsule son contenu. Dans ce cas, RecyclerView sera “aussi grand que les vues internes”, il n’aura donc pas de barre de défilement et l’utilisateur utilisera les capacités de défilement de NestedScrollView. Par conséquent, il ne sera pas ambigu comme “défilement à l’intérieur du défilement”.

Il y a un code simple et de test que vous pouvez vérifier

    

Voici le code que j’utilise pour éviter les problèmes de défilement:

 mRecyclerView = (RecyclerView) view.findViewById(android.R.id.list); mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); mRecyclerView.getLayoutManager().setAutoMeasureEnabled(true); mRecyclerView.setNestedScrollingEnabled(false); mRecyclerView.setHasFixedSize(false); 

J’ai utilisé RecyclerView dans un NestedScrollView et cela a fonctionné pour moi. Le seul truc que je devais garder à l’esprit était qu’un NestedScrollView ne prend qu’une seule vue enfant. Donc, dans mon cas, j’ai utilisé le groupe de consultation LienearLayout qui abritait mon RecyclerView et plusieurs autres vues dont j’avais besoin.

J’ai rencontré un problème en mettant mon RecyclerView dans NestedScrollView. J’ai réalisé que le défilement du contenu de mon RecyclerView était relâché.

Je me suis rendu compte plus tard que mon RecyclerView recevait l’événement de défilement et était donc en conflit avec le comportement de défilement de NestedScrollView.

Donc, pour résoudre ce problème, j’ai dû désactiver la fonctionnalité de défilement de mon RecyclerView avec cette méthode movieListNewRecyclerView.setNestedScrollingEnabled(false);

Vous pouvez commander mon Instagram pour une courte vidéo de ce que j’ai réellement fait. Ceci est ma poignée d’instagram ofelix03

Cliquez sur cette image pour voir ce que j’ai fait

Si vous utilisez RecyclerView-23.2.1 ou une version ultérieure. La solution suivante fonctionnera très bien:

Dans votre mise en page, ajoutez RecyclerView comme ceci:

  

Et dans votre fichier java:

 RecyclerView mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView); LinearLayoutManager layoutManager=new LinearLayoutManager(getContext()); layoutManager.setAutoMeasureEnabled(true); mRecyclerView.setLayoutManager(layoutManager); mRecyclerView.setHasFixedSize(true); mRecyclerView.setAdapter(new YourListAdapter(getContext())); 

Ici layoutManager.setAutoMeasureEnabled(true); fera le tour.

Consultez ce numéro et ce blog pour plus d’informations.

J’ai Viewpager et RecyclerView dans le NestedScrollView. Après avoir ajouté les lignes ci-dessous

 recyclerView.setNestedScrollingEnabled(false); recyclerView.setHasFixedSize(false); 

J’ai résolu les problèmes de défilement lent et de défilement.

Vous ne pouvez pas utiliser une vue de recycleur dans une vue de défilement nestede. Il n’est pas destiné à contenir d’autres vues défilantes, mais c’est parce que c’est un enfant d’une présentation défilante elle-même que vous avez besoin de la vue de défilement nestede. J’avais le même problème, mais à la fin j’ai déplacé ma textview pour en faire une vue d’ensemble au sein de la recyclerview, fait de la recyclerview un élément direct de la disposition du coordinateur et supprimé la vue de défilement nestede. Ensuite, tous mes problèmes ont disparu.

J’ai dû implémenter CoordinatorLayout avec le défilement de la barre d’outils et cela m’a pris toute la journée pour contourner ce problème. Je l’ai fait en supprimant NestedScrollView du tout. Donc, j’utilise simplement RelativeLayout à la racine.

     

RecyclerView avec NestedScrollView