Comment utiliser RecyclerView dans NestedScrollView?

210

Comment utiliser à l' RecyclerViewintérieur NestedScrollView? RecyclerViewle contenu n'est pas visible après avoir configuré l'adaptateur.

MISE À JOUR du code de mise en page.

<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>
Mecid
la source
@Mecid Il n'y a aucune raison d'utiliser un RecyclerView dans un ScrollView (ou NestedScrollView).
Gabriele Mariotti
2
@Mecid, vous ne devez jamais placer une vue défilante dans une autre vue défilante. C'est une règle générale sous Android.
Gabriele Mariotti
6
@GabrieleMariotti je connais cette règle, mais NestedScrollView a été développé pour résoudre ce problème.
Mecid
1
Ce n'est pas correct. NestedScrollView est exactement comme ScrollView, mais il prend en charge le rôle de parent et d'enfant à défilement imbriqué. Dans votre cas, vous devez définir votre propre comportement de défilement.
Gabriele Mariotti

Réponses:

216

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"

va gérer le reste des choses.

Encore une chose, pas besoin de mettre votre recycleurView dans NestedScrollView

Rahul Upadhyay
la source
33
Je ne comprends pas pourquoi cette solution n'obtient pas le plus de votes positifs. Ce n'est pas réalisé avec NestedScrollViewmais juste avec app:layout_behavior="@string/appbar_scrolling_view_behavior". Telle est la clé!
Hata
3
@RahulUpadhyay, cela a fonctionné pour moi, mais je pense que votre dernière ligne est erronée, le RecyclerView ne montre pas du tout s'il est à l'intérieur d'un NestedScrollView. Cependant, vous êtes une superstar: D
Leon
3
Ça marche! il suffit de mettre à jour la compilation de la bibliothèque de recyclage 'com.android.support:recyclerview-v7:+'
Fabio Guerra
28
Cette solution est destinée à être utilisée avec CoordinatorLayout, AppBarLayoutet le réglage approprié layout_scrollFlagssur la ou les vues enfant à faire défiler avec RecyclerView. Je ne sais pas pourquoi cela a été omis de la réponse. Sinon, c'est une solution agréable et simple.
Sanvywell
9
Je pense qu'il est très important de comprendre que le RECYCLAGE de RecyclerView NE FONCTIONNERA PAS ici. Par conséquent, si vous avez une longue liste d'éléments, elle apparaîtra avec un gel notable de l'interface utilisateur.
Gaket
121

MISE À JOUR 1

Depuis la bibliothèque de support Android 23.2.0, une méthode a été ajoutée setAutoMeasureEnabled(true)pour les 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

Alors ajoutez simplement quelque chose comme ceci:

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


MISE À JOUR 2

Étant donné que 27.1.0 setAutoMeasureEnabledest obsolète, vous devez donc fournir une implémentation personnalisée de LayoutManager avec la méthode substituéeisAutoMeasureEnabled()

Mais après de nombreux cas d'utilisation de RecyclerView, je recommande fortement de ne pas l'utiliser dans mode d'emballage , car ce n'est pas ce à quoi il est destiné. Essayez de refaçonner l'ensemble de votre mise en page en utilisant un seul RecyclerView normal avec plusieurs types d'éléments. Ou utilisez l'approche avec LinearLayout que j'ai décrite ci-dessous en dernier recours


Ancienne réponse (non recommandée)

Vous pouvez utiliser à l' RecyclerViewintérieur NestedScrollView. Tout d'abord, vous devez implémenter votre propre personnalisation LinearLayoutManager, cela vous permet RecyclerViewd'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 ceci LayoutManagerpour votreRecyclerView

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

Mais vous devez également appeler ces deux méthodes:

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

Ici, setNestedScrollingEnabled(false)désactivez le défilement pour RecyclerView, afin qu'il n'intercepte pas l'événement de défilement de NestedScrollView. EtsetHasFixedSize(false) déterminez que les modifications du contenu de l'adaptateur peuvent modifier la taille duRecyclerView

Remarque importante: cette solution est peu buggée dans certains cas et a des problèmes de performances, donc si vous avez beaucoup d'éléments dans votre, RecyclerViewje vous recommande d'utiliser une LinearLayoutimplémentation personnalisée de l'affichage de liste, de créer l'analogue de l'adaptateur pour cela et de le faire se comporter comme ListViewouRecyclerView

smbd uknow
la source
19
Mise en garde! Ne l'utilisez pas si vous avez beaucoup d'articles dans votre RecyclerView.
Brais Gabin
1
@BraisGabin, vous avez raison: setHasFixedSize (false) provoque un rafraîchissement multiple de RecyclerView, donc s'il contient beaucoup d'éléments, cela fonctionnera très lentement. Dans ces cas, j'utilise LinearLayout avec une sorte d '"adaptateur" personnalisé pour qu'il se comporte comme ListView ou RecyclerView
smbd uknow
1
Merci beaucoup! M'a sauvé des heures. Soit dit en passant, le dernier élément de décoration n'est pas affiché avec ce gestionnaire de mise en page (et uniquement avec celui-ci), bug possible?
Jjang
2
setAutoMeasureEnabled est obsolète à partir du niveau API 27.1.0 developer.android.com/reference/android/support/v7/widget/…
Dika
2
remplacer la valeur booléenne isAutoMeasureEnabled () à la place. it Renvoie si la passe de mesure de la mise en page doit utiliser le mécanisme AutoMeasure de RecyclerView ou si elle doit être effectuée par l'implémentation de LayMonManager de onMeasure (Recycler, State, int, int). Cette méthode retourne false par défaut (elle retourne en fait la valeur passée à setAutoMeasureEnabled (booléen) obsolète) et doit être remplacée pour retourner true si un LayoutManager veut être mesuré automatiquement par RecyclerView. Si cette méthode est substituée pour retourner true, onMeasure (Recycler, State, int, int) ne doit pas être surchargé.
Peterstev Uremgba
100

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

2) et la RecyclerViewhauteur serawrap_content .

3) recyclerView.setNestedScrollingEnabled(false)

Mais en faisant cela, le modèle de recycleur ne fonctionne pas . (c.-à-d. que toutes les vues seront chargées en une seule fois, car elles ont wrap_contentbesoin de la hauteur complète RecyclerViewpour qu'elles dessinent tous les enfants Views at once. No view will be recycled). Try not to use this pattern unless it is really required. Try to useviewType and add all other views that need to scroll toRecyclerView rather than usingRecyclerView inScrollview`. L'impact sur les performances sera très élevé.

Pour faire simple "il agit comme LinearLayoutavec toutes les vues enfant"

Ashok Varma
la source
6
Merci @Ashok. Le réglage recyclerView.setNestedScrollingEnabled(false)m'a aidé à avoir un défilement fluide.
Shubhral
3
Cela devrait être la réponse acceptée! faites-le bien remarquer qu'aucune vue ne sera recyclée et que toute la vue sera dessinée en même temps.
M'hamed
3
@AshokVarma, même problème auquel je fais face maintenant. mais scroll fonctionne très bien à l'intérieur de recyclerView mais je n'ai pas pu implémenter Endless scroll pour recyclerview parce que toutes les vues de recyclerview se dessinent en même temps, ce qui conduit à continuer d'appeler le service Web. alors comment puis-je gérer cela?
Anantha Babu
@AnanthaBabu au lieu d'utiliser recyclerview dans un scrollview. convertir tous les éléments de la vue déroulante en éléments de la vue recycleur. vous pouvez utiliser le type de vue recyclerviews et peindre différents types de dispositions. Il existe également de bonnes bibliothèques pour les gérer (utilisez des bibliothèques si vous avez une structure de vue vraiment compliquée et si vous voulez des composants réutilisables).
Ashok Varma
1
@AshokVarma existe-t-il une solution au problème de comportement du recycleur? Je ne veux pas que recyclerview dessine tous les enfants d'un seul coup.
andro-girl
36

Vous pouvez utiliser android:fillViewport="true"pour NestedScrollViewmesurer le RecyclerView. Le RecyclerViewremplira la hauteur restante. donc si vous voulez faire défiler la NestScrollView, vous pouvez définir les RecyclerView« s minHeight.

zayn
la source
15
si vous avez un aperçu du recyclage de 200 articles et que vous le faites, le nidcrollview se développera pour remplir les 200 articles entiers!
RJFares
1
@RJFares Ce n'est jamais arrivé. J'essaie une démo et j'utilise LayoutInspector pour inspecter la mise en page, cela fonctionne bien. Pouvez-vous fournir les versions de votre recyclerView?
zayn
26

Ajouter simplement recyclerView.setNestedScrollingEnabled(false);avant setAdapterlui-même a fonctionné pour moi. Je n'ai ajouté app:layout_behavior="@string/appbar_scrolling_view_behavior"aucun endroit et je n'ai défini aucun gestionnaire de 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>
Vignesh Sundar
la source
10
Mais maintenant, il ne recycle plus les vues?
Mark Buikema
Non, il va recycler, non?
Vignesh Sundar
6
non, j'ai essayé avec une mise en page très complexe avec 200 éléments, le nestedscrollview se développe juste à la taille de ses enfants donc il va s'étendre, donc aucun recyclage ne se produira @MarkBuikema avez-vous réussi à trouver une meilleure solution?
RJFares
20

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>
Ness Tyagi
la source
4
Vous pouvez supprimer la deuxième application: layout_behavior = "@ string / appbar_scrolling_view_behavior". Comme le comportement ne fonctionne que pour les enfants directs de CoordinatorLayout.
Pepster
2
De plus, il est important de mentionner que vous devez avoir la disposition Coordinateur comme disposition racine. Ce n'est pas toujours vrai.
Gaket
10

Il existe un code simple et de test que vous pouvez 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>
Hakim Khan
la source
9

Car androidxil s'appelle androidx.core.widget.NestedScrollView- et il défile également comme du beurre avec des propriétés isScrollContaineret measureAllChildrenactivé:

<!-- Scrolling Content -->
<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"

    android:isScrollContainer="true"
    android:measureAllChildren="true"

    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fastScrollEnabled="true"
        android:scrollbarStyle="insideInset"
        android:scrollbars="vertical"
        android:splitMotionEvents="false"
        android:verticalScrollbarPosition="right"/>

</androidx.core.widget.NestedScrollView>
Martin Zeitler
la source
7

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

LayoutManager de la bibliothèque fait recyclerView enveloppe son contenu. Dans ce cas, RecyclerView sera "aussi grand que les vues intérieures", il n'aura donc 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 "scrollable inside scrollable".

alcsan
la source
1
Voici la classe de LinearLayoutManager de cette bibliothèque: github.com/serso/android-linear-layout-manager/blob/master/lib/…
Ninja Coding
6

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);
Anton Tananaev
la source
6

J'ai utilisé RecyclerView dans un NestedScrollView et cela a fonctionné pour moi. Le seul problème 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 vues LienearLayout qui hébergeait mon RecyclerView et un certain nombre d'autres vues dont j'avais besoin.

Je rencontre un problème en plaçant mon RecyclerView dans le NestedScrollView. J'ai réalisé que le défilement du contenu de mon RecyclerView était ralenti.

J'ai réalisé plus tard que mon RecyclerView recevait l'événement de défilement et était donc en conflit avec le comportement de défilement du 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 consulter mon Instagram pour une courte vidéo de ce que j'ai réellement fait. C'est ma poignée instagram ofelix03

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

Felix Otoo
la source
5

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 le problème de défilement lent et de retard de défilement.

Isham
la source
3
Tu ne veux pas dire recyclerView.setHasFixedSize(true);?
Keno Clayton
3

Vous ne pouvez pas utiliser une vue de recycleur dans une vue de défilement imbriquée. Il n'est pas destiné à contenir d'autres vues défilables, mais c'est parce que c'est un enfant d'une disposition de défilement lui-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é ma vue de texte pour être une vue de tête dans la vue de recyclage, j'ai fait de la vue de recyclage un enfant direct de la disposition du coordinateur et j'ai supprimé la vue de défilement imbriquée. Ensuite, tous mes problèmes ont disparu.

Barry Irvine
la source
8
Depuis RecyclerViewimplémente NestedScrollingChild, RecyclerViewdevrait pouvoir être défilé via NestedScrollView.
Benjamin
Je viens de voter pour rejeter stackoverflow.com/review/suggested-edits/9907622 basé uniquement sur les erreurs anglaises, mais il peut y avoir du contenu de valeur là-dedans - toute personne de passage connaissant le sujet devrait jeter un oeil et voir si elle peut le nettoyer. S'il n'y a rien d'utile, signalez ce commentaire pour suppression par les mods.
Mark Amery
3

Si vous utilisez RecyclerView-23.2.1ou 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.

Consultez ce problème et ce blog de développeur pour plus d'informations.

uniruddh
la source
Soyez prudent en utilisant "mRecyclerView.setHasFixedSize (true);" bien que. Vous ne pouvez l'utiliser que si vous n'ajoutez pas ou ne supprimez pas d'éléments de la vue du recycleur au moment de l'exécution.
Gaket
2

Une solution pour conserver la fonction de recyclage de la vue de recyclage et éviter que la vue de recyclage charge toutes vos données consiste à définir une hauteur fixe dans la vue de recyclage elle-même. En faisant cela, la vue d'ensemble du recyclage est limitée uniquement à charger autant que sa hauteur peut montrer à l'utilisateur recyclant ainsi son élément si jamais vous faites défiler vers le bas / haut.

Christian Callelero
la source
2

Il y a beaucoup de bonnes réponses. La clé est que vous devez définir nestedScrollingEnabledà false. Comme mentionné ci-dessus, vous pouvez le faire en code java:

mRecyclerView.setNestedScrollingEnabled(false);

Mais vous avez également la possibilité de définir la même propriété dans le code xml ( android:nestedScrollingEnabled="false"):

 <android.support.v7.widget.RecyclerView
 android:id="@+id/recyclerview"
 android:nestedScrollingEnabled="false"
 android:layout_width="match_parent"
 android:layout_height="match_parent" />
Alex Misiulia
la source
2

Si vous utilisez RecyclerView ScrollListener dans NestedScrollView , l'écouteur addOnScrollListener ne fonctionne pas correctement si vous êtes utilisé les deux.

Utilisez ce code.

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState); 
              ......
        }
    });

ce code fonctionne correctement RecyclerView ScrollListener dans NestedScrollView .

Merci

Rahul
la source
1

J'ai dû implémenter CoordinatorLayout avec le défilement de la barre d'outils et cela m'a juste pris toute la journée à déconner. Je l'ai fait fonctionner en supprimant NestedScrollView du tout. Je n'utilise donc que 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>
Bogdan Ustyak
la source
1

n'utilisez pas recyclerView dans NestedScrollView. cela peut provoquer des problèmes de cascade! Je suggère d'utiliser ItemViewTypes dans RecyclerView pour gérer plusieurs types de vues. ajoutez simplement un RecyclerView avec la largeur et la hauteur de match_parent. puis dans votre recyclerViewAdapter, remplacez getItemViewType et utilisez position pour gérer la disposition à gonfler. après cela, vous pouvez gérer votre détenteur de vue en utilisant la méthode onBindViewHolder.

Hossein Karami
la source
1
nestedScrollView.setNestedScrollingEnabled(true);

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            //...
        }
    });


<androidx.core.widget.NestedScrollView
    android:id="@+id/nested"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    android:layout_below="@id/appBarLayout_orders"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"> 

    <androidx.constraintlayout.widget.ConstraintLayout ...

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"/>
Braian Coronel
la source
0

J'ai utilisé cette extension géniale (écrite en kotlin mais peut également être utilisée en Java)

https://github.com/Widgetlabs/expedition-nestedscrollview

Fondamentalement, vous obtenez l' NestedRecyclerViewintérieur de n'importe quel paquet, disons des utils dans votre projet, puis créez simplement votre vue de recyclage comme

 <com.your_package.utils.NestedRecyclerView
      android:id="@+id/rv_test"
      android:layout_width="match_parent"
      android:layout_height="match_parent" />

Consultez cet article génial de Marc Knaup

https://medium.com/widgetlabs-engineering/scrollable-nestedscrollviews-inside-recyclerview-ca65050d828a

Gastón Saillén
la source
0

Solution pour ne pas charger tous les enfants recyclew view à la fois dans la vue de défilement imbriquée .

Bénéfices:

  1. ne charge pas tous les enfants une fois, lors de l'utilisation de la vue de défilement imbriquée.
  2. vous pouvez utiliser recycleView.setHasFixedSize (true) pour de meilleures performances
  3. empêcher les services Web d'envoyer toutes les données en même temps, la pagination fonctionne comme prévu
  4. bon pour un plus grand nombre d'ensembles de données.
  5. bon pour les appareils à faible mémoire
  6. peut continuer à utiliser le défilement imbriqué
  7. très utile lorsque votre recyle affiche un élément complexe et nécessite beaucoup de ressources.

Réparer :

dans votre xml au lieu d'utiliser match_parent ou wrap_content pour recycleview, utilisez la hauteur fixe .

Abhishek Garg
la source
0

Dans mon cas, l'enfant de NestedScrollview est ConstraintLayout. Cela ne fonctionne pas comme prévu, je l'ai remplacé par LinearLayout. Peut-être que cela aide quelqu'un.

<androidx.core.widget.NestedScrollView 
  android:id="@+id/nestedScrollView" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent">

  <LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:descendantFocusability="blocksDescendants">

    <androidx.recyclerview.widget.RecyclerView
      android:id="@+id/recyclerView"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:nestedScrollingEnabled="false"
      app:layout_constraintBottom_toTopOf="@+id/divider"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toBottomOf="@+id/tinTitle"/>

  </LinearLayout>
</androidx.core.widget.NestedScrollView>
nAkhmedov
la source
-5

RecyclerView avec NestedScrollView

    <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" />
devangi chhatbar
la source