Comment utiliser RecyclerView dans NestedScrollView?
comment utiliser RecyclerView
dans NestedScrollView
?
Le contenu RecyclerView
n'est pas visible après le réglage de l'adaptateur.
mise à JOUR mise en page de code mis à jour.
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/keyline_1">
</RelativeLayout>
<View
android:id="@+id/separator"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#e5e5e5" />
<android.support.v7.widget.RecyclerView
android:id="@+id/conversation"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
15 réponses
remplacez votre recyclerView par,
<android.support.v7.widget.RecyclerView
android:id="@+id/conversation"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
ici,
app:layout_behavior="@string/appbar_scrolling_view_behavior"
gérera le reste.
encore une chose, pas besoin de mettre votre recyclerView à L'intérieur de NestedScrollView
mise à JOUR
depuis Android Support Library 23.2.0 il a été ajouté la méthode setAutoMeasureEnabled(true)
pour LayoutManagers. Il fait RecyclerView pour envelopper son contenu et fonctionne comme un charme.
http://android-developers.blogspot.ru/2016/02/android-support-library-232.html
il suffit donc d'ajouter quelque chose comme ceci:
LayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setAutoMeasureEnabled(true);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setNestedScrollingEnabled(false);
Vieille réponse (non recommandé)
vous pouvez utiliser RecyclerView
à l'intérieur de NestedScrollView
.
Tout d'abord , vous devez mettre en œuvre votre propre coutume LinearLayoutManager
, il fait 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 cette utilisation de 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ésactiver le défilement pour RecyclerView
, de sorte qu'il n'intercepte pas l'événement de défilement de NestedScrollView
. Et setHasFixedSize(false)
déterminer que les changements dans le contenu de l'adaptateur peut changer la taille de la RecyclerView
Note importante: Cette solution est peu boguée dans certains cas et a des problèmes avec perfomance, donc si vous avez beaucoup d'articles dans votre RecyclerView
je recommande d'utiliser l'implémentation personnalisée LinearLayout
de la vue de liste, créer l'analogue de L'Adaptateur pour elle et la faire se comporter comme ListView
ou RecyclerView
1519230920"
1) vous devez utiliser la bibliothèque de soutien 23.2.0 (ou) ci-dessus
2) et RecyclerView
hauteur sera wrap_content
.
3) recyclerView.setNestedScrollingEnabled(false)
mais en faisant cela le modèle de recycleur ne fonctionne pas. (I. e toutes les vues seront chargées à la fois parce que wrap_content
a besoin de la hauteur de RecyclerView
complète ainsi il dessinera tous les enfants View
à la fois. Aucune vue ne sera recyclée). Essayez de ne pas utiliser ce modèle jusqu'à que si cela est vraiment nécessaire. Essayez d'utiliser viewType
et ajoutez toutes les autres vues qui doivent faire défiler vers RecyclerView
plutôt que d'utiliser RecyclerView
dans Scrollview
. L'impact sur le rendement sera très élevé.
Pour faire simple "il agit comme LinearLayout
avec toutes les vues enfant"
vous pouvez utiliser android:fillViewport="true"
pour faire NestedScrollView
mesurer le RecyclerView
. Le RecyclerView
remplira la hauteur restante. donc, si vous voulez faire défiler l' NestScrollView
, vous pouvez définir le RecyclerView
's minHeight
.
en ajoutant simplement recyclerView.setNestedScrollingEnabled(false);
avant setAdapter
lui-même a fonctionné pour moi. Je n'ai pas ajouté app:layout_behavior="@string/appbar_scrolling_view_behavior"
n'importe où et n'ai pas mis n'importe quel directeur de la mise en page personnalisé
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:text="Some Text..."
android:padding="15dp" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:padding="15dp"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Quick Links"
android:textColor="@color/black"
android:textStyle="bold"
android:textAllCaps="true"
android:paddingLeft="20dp"
android:drawableLeft="@drawable/ic_trending_up_black_24dp"
android:drawablePadding="10dp"
android:layout_marginBottom="10dp"
android:textSize="16sp"/>
<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="#efefef"/>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
c'est ce qui fonctionne pour moi
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.v4.widget.NestedScrollView>
essayez d'utiliser cette bibliothèque - https://github.com/serso/android-linear-layout-manager .
LayoutManager de la bibliothèque rend RecyclerView enveloppe son contenu. Dans ce cas, RecyclerView sera "aussi grand que des vues intérieures", de sorte qu'il n'aura pas de barres 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 de défilement".
il y a un code simple et de test u peut vérifier
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v4.widget.NestedScrollView>
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 inside a NestedScrollView et cela a fonctionné pour moi. Le seul gotcha que j'ai eu à garder à l'esprit était qu'un ScrollView nested ne prend qu'une seule vue d'enfant. Dans mon cas, J'ai utilisé le viewgroup de LienearLayout qui hébergeait mon RecyclerView ainsi qu'un certain nombre d'autres vues dont j'avais besoin.
je fais l'expérience d'un problème mettant mon RecyclerView à l'intérieur du nested ScrollView. J'ai réalisé que défiler le contenu de ma RecyclerView s'est effondrée.
plus tard, j'ai réalisé que mon RecyclerView recevait l'événement de défilement et était donc en conflit avec le comportement de défilement du NestedScrollView.
pour résoudre ce problème, j'ai dû désactiver la fonction de défilement de mon RecyclerView avec cette méthode movieListNewRecyclerView.setNestedScrollingEnabled(false);
vous pouvez consulter mon Instagram pour une courte vidéo de ce que j'ai réellement fait. C'est mon stylo instagram ofelix03
Si vous utilisez RecyclerView-23.2.1
ou plus tard. La solution suivante fonctionnera très bien:
dans votre mise en page ajoutez RecyclerView comme ceci:
<android.support.v7.widget.RecyclerView
android:id="@+id/review_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" />
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 l'affaire.
Check out cette question et ce blog des développeurs pour plus d'informations.
J'ai Viewpager et RecyclerView à l'intérieur de NestedScrollView. Après avoir ajouté les lignes
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(false);
j'ai résolu le problème du retard de défilement et de défilement lent.
vous ne pouvez pas utiliser une vue recycler dans une vue de rouleau emboîté. Il n'est pas destiné à contenir d'autres vues de défilement, mais c'est parce que c'est un enfant d'une disposition de défilement elle-même que vous avez besoin de la vue de défilement imbriquée. J'ai eu le même problème mais à la fin j'ai déplacé mon textview pour être un headerview dans le recyclerview, fait le recyclerview un enfant direct de la mise en page de coordinateur et supprimé la vue de rouleau emboîté. Ensuite, tous mes problèmes ont disparu.
j'ai dû mettre en place CoordinatorLayout avec barre d'outils défilant et ça m'a pris toute la journée à jouer avec ça. Je l'ai fait fonctionner en supprimant NestedScrollView du tout. Donc J'utilise RelativeLayout à la racine.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_nearby"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</RelativeLayout>
RecyclerView with nested ScrollView
<android.support.v7.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />