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.