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>
156
demandé sur Tom11 2015-06-23 13:18:18

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

165
répondu Rahul Upadhyay 2015-09-23 09:00:15

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"

102
répondu smbd uknow 2017-08-25 14:33:08

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"

75
répondu Ashok Varma 2018-03-27 06:56:24

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 .

32
répondu zayn 2015-07-25 08:39:01

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>
25
répondu Vignesh Sundar 2017-07-05 10:06:14

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>
19
répondu Ness Tyagi 2016-05-23 19:12:00

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".

7
répondu alcsan 2015-11-25 17:46:58

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>
7
répondu Hakim Khan 2016-09-24 07:04:41

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);
5
répondu Anton Tananaev 2016-11-03 02:57:15

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

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

5
répondu Felix Otoo 2017-01-12 10:16:41

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.

3
répondu astuter 2016-07-24 10:41:50

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.

3
répondu Isham 2016-09-30 12:35:31

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.

1
répondu Barry Irvine 2015-08-04 20:24:34

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>
1
répondu Bogdan Ustyak 2016-10-02 17:05:40

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" />
-5
répondu devangi chhatbar 2017-03-14 11:33:04