Wie verwende ich RecyclerView in NestedScrollView?


210

Wie benutzt man RecyclerViewdrinnen NestedScrollView? RecyclerViewInhalt ist nach dem Einstellen des Adapters nicht sichtbar.

UPDATE- Layoutcode aktualisiert.

<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 Es gibt keine Gründe, eine RecyclerView in einer ScrollView (oder NestedScrollView) zu verwenden.
Gabriele Mariotti

2
@Mecid Sie sollten niemals eine scrollbare Ansicht in eine andere scrollbare Ansicht einfügen. Dies ist eine allgemeine Regel in Android.
Gabriele Mariotti

6
@ GabrieleMariotti Ich kenne diese Regel, aber NestedScrollView wurde entwickelt, um dieses Problem zu beheben.
Mecid

1
Es ist nicht richtig. NestedScrollView ähnelt ScrollView, unterstützt jedoch die Funktion als verschachteltes übergeordnetes und untergeordnetes Bild. In Ihrem Fall müssen Sie Ihr eigenes Bildlaufverhalten definieren.
Gabriele Mariotti

Antworten:


216

Ersetzen Sie Ihre recyclerView durch,

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

Hier,

app:layout_behavior="@string/appbar_scrolling_view_behavior"

wird den Rest der Dinge verwalten.

Außerdem müssen Sie Ihre recyclerView nicht in NestedScrollView ablegen


33
Ich kann nicht verstehen, warum diese Lösung nicht die meisten Stimmen erhält. Es wird nicht mit, NestedScrollViewsondern nur mit erreicht app:layout_behavior="@string/appbar_scrolling_view_behavior". Das ist der Schlüssel!
Hata

3
@RahulUpadhyay das hat bei mir funktioniert, aber ich denke deine letzte Zeile ist falsch, die RecyclerView wird überhaupt nicht angezeigt, wenn sie sich in einer NestedScrollView befindet. Sie sind jedoch ein Superstar: D
Leon

3
Es klappt! Aktualisieren Sie einfach die Kompilierung der recyclerview-Bibliothek 'com.android.support:recyclerview-v7:+'
Fabio Guerra

28
Diese Lösung soll mit verwendet werden CoordinatorLayout, AppBarLayoutund entsprechende Einstellung layout_scrollFlagsauf der untergeordneten Ansicht (n) , die mit dem gescrollt werden soll RecyclerView. Ich bin mir nicht sicher, warum dies in der Antwort weggelassen wurde. Ansonsten ist dies eine schöne und einfache Lösung.
Sanvywell

9
Ich denke, es ist sehr wichtig zu verstehen, dass RecyclerView RECYCLING hier NICHT FUNKTIONIERT. Wenn Sie eine lange Liste von Elementen haben, wird diese daher mit einem merklichen Einfrieren der Benutzeroberfläche angezeigt.
Gaket

121

UPDATE 1

Seit Android Support Library 23.2.0 wurden Methoden setAutoMeasureEnabled(true)für LayoutManager hinzugefügt . Dadurch kann RecyclerView den Inhalt verpacken und wirkt wie ein Zauber.
http://android-developers.blogspot.ru/2016/02/android-support-library-232.html

Fügen Sie einfach so etwas hinzu:

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


UPDATE 2

Da 27.1.0 setAutoMeasureEnabledveraltet ist, sollten Sie die benutzerdefinierte Implementierung von LayoutManager mit überschriebener Methode bereitstellenisAutoMeasureEnabled()

Nach vielen Fällen der Verwendung von RecyclerView empfehle ich jedoch dringend, es nicht im Wrapping-Modus zu verwenden , da dies nicht der Zweck ist. Versuchen Sie, Ihr gesamtes Layout mit normaler RecyclerView mit mehreren Elementtypen neu zu gestalten. Oder verwenden Sie den Ansatz mit LinearLayout, den ich unten als letzten Ausweg beschrieben habe


Alte Antwort (nicht empfohlen)

Sie können RecyclerViewinnen verwenden NestedScrollView. Zuallererst sollten Sie Ihre eigene Gewohnheit implementieren LinearLayoutManager, damit Sie RecyclerViewden Inhalt einpacken können. Beispielsweise:

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);
    }
}

Danach verwenden Sie dies LayoutManagerfür IhreRecyclerView

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

Sie sollten diese beiden Methoden aber auch aufrufen:

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

Hier setNestedScrollingEnabled(false)deaktivieren Scrollen für RecyclerView, so dass es nicht abfangen Scrollen Ereignis aus NestedScrollView. Und stellen Sie setHasFixedSize(false)fest, dass Änderungen am Adapterinhalt die Größe des ändern könnenRecyclerView

Wichtiger Hinweis: Diese Lösung ist in einigen Fällen wenig fehlerhaft und weist Probleme mit der Leistung auf. Wenn Sie also viele Elemente in Ihrem Programm haben, würde RecyclerViewich empfehlen, eine benutzerdefinierte LinearLayoutImplementierung der Listenansicht zu verwenden , ein Analogon des Adapters dafür zu erstellen und es zu erstellen benimm dich wie ListViewoderRecyclerView


19
Vorsicht! Verwenden Sie dies nicht, wenn Sie viele Gegenstände in Ihrem haben RecyclerView.
Brais Gabin

1
@BraisGabin, Sie haben Recht: setHasFixedSize (false) bewirkt eine mehrfache Aktualisierung von RecyclerView. Wenn es also viele Elemente enthält, funktioniert es sehr langsam. In diesen Fällen verwende ich LinearLayout mit einer Art benutzerdefiniertem "Adapter", damit es sich wie ListView oder RecyclerView
verhält

1
Vielen Dank! Hat mir Stunden gespart. Übrigens wird die letzte Artikeldekoration mit diesem Layout-Manager nicht angezeigt (und nur mit diesem), möglicher Fehler?
Jjang

2
setAutoMeasureEnabled ist ab API-Level 27.1.0 veraltet. developer.android.com/reference/android/support/v7/widget/…
Dika

2
Überschreiben Sie stattdessen den booleschen Wert isAutoMeasureEnabled (). Es gibt zurück, ob der Messdurchlauf des Layouts den AutoMeasure-Mechanismus von RecyclerView verwenden soll oder ob dies durch die Implementierung von onMeasure durch den LayoutManager (Recycler, State, int, int) erfolgen soll. Diese Methode gibt standardmäßig false zurück (sie gibt tatsächlich den Wert zurück, der an das veraltete setAutoMeasureEnabled (boolean) übergeben wurde) und sollte überschrieben werden, um true zurückzugeben, wenn ein LayoutManager von RecyclerView automatisch gemessen werden soll. Wenn diese Methode überschrieben wird, um true zurückzugeben, sollte onMeasure (Recycler, State, int, int) nicht überschrieben werden.
Peterstev Uremgba

100

1) Sie müssen die Support-Bibliothek 23.2.0 (oder) oben verwenden

2) und RecyclerViewHöhe wird seinwrap_content .

3) recyclerView.setNestedScrollingEnabled(false)

Auf diese Weise funktioniert das Recycler-Muster jedoch nicht . (dh alle Ansichten werden auf einmal geladen, da wrap_contentdie Höhe vollständig sein muss, RecyclerViewdamit alle Views at once. No view will be recycled). Try not to use this pattern unless it is really required. Try to useuntergeordneten Ansichten gezeichnet werden. Typ and add all other views that need to scroll toRecyclerView rather than usingRecyclerView inScrollview`. Die Auswirkungen auf die Leistung sind sehr hoch.

Um es einfach zu machen "es verhält sich einfach wie LinearLayoutbei allen untergeordneten Ansichten"


6
Danke @Ashok. Die Einstellung recyclerView.setNestedScrollingEnabled(false)hat mir geholfen, eine glatte Schriftrolle zu haben.
Shubhral

3
Dies sollte die akzeptierte Antwort sein! weil es gut darauf hinweist, dass keine Ansicht recycelt wird und die gesamte Ansicht auf einmal gezeichnet wird.
M'hamed

3
@AshokVarma, das gleiche Problem, mit dem ich jetzt konfrontiert bin. Aber scroll funktioniert in recyclerView einwandfrei, aber ich konnte Endless scroll für recyclerview nicht implementieren, da alle Ansichten von recyclerview-Zeichnungen gleichzeitig angezeigt werden, sodass der Webdienst weiterhin aufgerufen wird. Wie kann ich damit umgehen?
Anantha Babu

@AnanthaBabu anstatt recyclerview in einer Bildlaufansicht zu verwenden. Konvertieren Sie alle Elemente in der Bildlaufansicht in Elemente in der Recycler-Ansicht. Sie können den Ansichtstyp recyclerviews verwenden und verschiedene Arten von Layouts malen. Es gibt auch einige gute Bibliotheken, um diese zu handhaben (Verwenden Sie Bibliotheken, wenn Sie eine wirklich komplizierte Ansichtsstruktur haben und wiederverwendbare Komponenten wünschen).
Ashok Varma

1
@AshokVarma Gibt es eine Lösung für das Problem des Recyclingverhaltens? Ich möchte nicht, dass recyclerview alle Kinder auf einmal zeichnet.
Andro-Mädchen

36

Sie können verwenden android:fillViewport="true", um die zu NestedScrollViewmessen RecyclerView. Das RecyclerViewfüllt die verbleibende Höhe. also , wenn Sie die blättern möchten NestScrollView, können Sie die Set RecyclerView‚s minHeight.


14
Wenn Sie eine Recycling-Ansicht von 200 Elementen haben und dies tun, wird die verschachtelte Bildansicht erweitert, um die gesamten 200 Elemente zu füllen!
RJFares

1
@RJFares Das ist noch nie passiert. Ich probiere eine Demo aus und benutze LayoutInspector, um das Layout zu überprüfen. Es funktioniert einfach gut. Können Sie die Versionen Ihres recyclerView bereitstellen?
Zayn

26

Einfach recyclerView.setNestedScrollingEnabled(false);vor sich setAdapterselbst hinzuzufügen hat bei mir funktioniert. Ich habe app:layout_behavior="@string/appbar_scrolling_view_behavior"nirgendwo etwas hinzugefügt und keinen benutzerdefinierten Layout-Manager festgelegt

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

10
Aber jetzt werden keine Ansichten mehr recycelt?
Mark Buikema

Nein, es wird recycelt, nicht wahr?
Vignesh Sundar

6
Nein, tut es nicht. Ich habe es mit einem sehr komplexen Layout mit 200 Elementen versucht. Die verschachtelte Ansicht wird nur auf die Größe ihrer untergeordneten Elemente erweitert, sodass sie erweitert wird. Daher findet kein Recycling statt. @MarkBuikema Haben Sie es geschafft, eine bessere Lösung zu finden?
RJFares

20

Das ist es, was für mich funktioniert

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

4
Sie können die zweite App entfernen : layout_behavior = "@ string / appbar_scrolling_view_behavior" Da das Verhalten nur für direkte Kinder von CoordinatorLayout funktioniert.
Pepster

2
Darüber hinaus ist es wichtig zu erwähnen, dass Sie das Koordinator-Layout als Root-Layout haben sollten. Es ist nicht immer wahr.
Gaket

10

Es gibt einen einfachen und testenden Code, den Sie überprüfen können

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

9

Denn androidxes heißt androidx.core.widget.NestedScrollView- und es scrollt auch Butter mit Eigenschaften isScrollContainerund measureAllChildrenaktiviert:

<!-- 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>

7

Versuchen Sie, diese Bibliothek zu verwenden - https://github.com/serso/android-linear-layout-manager .

Mit dem LayoutManager der Bibliothek wird der Inhalt von RecyclerView umbrochen. In diesem Fall ist RecyclerView "so groß wie innere Ansichten", hat also keine Bildlaufleisten und der Benutzer verwendet die Bildlauffunktionen von NestedScrollView. Daher ist es nicht mehrdeutig wie "scrollbar inside scrollable".


1
Dies ist die Klasse von LinearLayoutManager aus dieser Bibliothek: github.com/serso/android-linear-layout-manager/blob/master/lib/…
Ninja Coding

6

Hier ist der Code, den ich verwende, um Bildlaufprobleme zu vermeiden:

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

6

Ich habe RecyclerView in einem NestedScrollView verwendet und es hat bei mir funktioniert. Das einzige Problem, an das ich denken musste, war, dass eine NestedScrollView nur eine untergeordnete Ansicht enthält. In meinem Fall habe ich also die LienearLayout-Ansichtsgruppe verwendet, in der sich meine RecyclerView sowie eine Reihe anderer Ansichten befanden, die ich benötigte.

Ich habe ein Problem beim Einfügen meiner RecyclerView in die NestedScrollView. Ich stellte fest, dass das Scrollen des Inhalts meines RecyclerView nachließ.

Später stellte ich fest, dass mein RecyclerView das Bildlaufereignis empfing und daher mit dem Bildlaufverhalten von NestedScrollView in Konflikt stand.

Um dieses Problem zu lösen, musste ich die Bildlauffunktion meines RecyclerView mit dieser Methode deaktivieren movieListNewRecyclerView.setNestedScrollingEnabled(false);

Auf meinem Instagram kannst du ein kurzes Video von dem sehen, was ich tatsächlich getan habe. Dies ist mein Instagram-Handle von elix03

Klicken Sie auf dieses Bild, um zu sehen, was ich getan habe


5

Ich habe Viewpager und RecyclerView in der NestedScrollView. Nach dem Hinzufügen der folgenden Zeilen

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

Ich habe das Problem des langsamen Bildlaufs und der Bildlaufverzögerung gelöst.


3
Meinst du nicht recyclerView.setHasFixedSize(true);?
Keno Clayton

3

Sie können keine Recycler-Ansicht in einer verschachtelten Bildlaufansicht verwenden. Es ist nicht beabsichtigt, weitere scrollbare Ansichten zu enthalten, aber da es sich um ein untergeordnetes Bildlauflayout handelt, benötigen Sie die verschachtelte Bildlaufansicht. Ich hatte das gleiche Problem, aber am Ende habe ich meine Textansicht in eine Kopfansicht innerhalb der Recyclingansicht verschoben, die Recyclingansicht zu einem direkten untergeordneten Element des Koordinatorlayouts gemacht und die verschachtelte Bildlaufansicht gelöscht. Dann waren alle meine Probleme weg.


8
Da RecyclerViewGeräte NestedScrollingChild, RecyclerViewsollte über gescrollt werden können NestedScrollView.
Benjamin

Ich habe gerade dafür gestimmt, stackoverflow.com/review/suggested-edits/9907622 nur aufgrund der englischen Fehler abzulehnen , aber es kann einen Wertinhalt enthalten - jeder, der mit Kenntnissen des Themas vorbeikommt, sollte einen Blick darauf werfen und sehen, ob dies der Fall ist kann es aufräumen. Wenn es dort nichts Nützliches gibt, kennzeichne diesen Kommentar von mir zum Löschen durch die Mods.
Mark Amery

3

Wenn Sie RecyclerView-23.2.1oder später verwenden. Die folgende Lösung funktioniert einwandfrei:

Fügen Sie in Ihrem Layout RecyclerView folgendermaßen hinzu:

<android.support.v7.widget.RecyclerView
        android:id="@+id/review_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical" />

Und in Ihrer Java-Datei:

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()));

Hier layoutManager.setAutoMeasureEnabled(true); wird der Trick machen.

Weitere Informationen finden Sie in diesem Problem und in diesem Entwicklerblog .


Seien Sie vorsichtig mit "mRecyclerView.setHasFixedSize (true);" obwohl. Sie können es nur verwenden, wenn Sie zur Laufzeit keine Elemente zur Recycler-Ansicht hinzufügen oder daraus entfernen.
Gaket

2

Eine Lösung, um die Recyclingfunktion der Recyclingansicht beizubehalten und zu vermeiden, dass die Recyclingansicht alle Ihre Daten lädt, besteht darin, eine feste Höhe in der Recyclingansicht selbst festzulegen. Auf diese Weise kann die Recycling-Ansicht nur so viel geladen werden, wie die Höhe dem Benutzer anzeigen kann, sodass das Element recycelt wird, wenn Sie jemals nach unten / oben scrollen.


2

Es gibt viele gute Antworten. Der Schlüssel ist , dass Sie setzen müssen nestedScrollingEnabledzu false. Wie oben erwähnt, können Sie dies in Java-Code tun:

mRecyclerView.setNestedScrollingEnabled(false);

Sie haben aber auch die Möglichkeit, dieselbe Eigenschaft in xml code ( android:nestedScrollingEnabled="false") festzulegen :

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

2

Wenn Sie RecyclerView ScrollListener in NestedScrollView verwenden , funktioniert der Listener addOnScrollListener nicht ordnungsgemäß, wenn Sie beide verwenden.

Verwenden Sie diesen Code.

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

Dieser Code funktioniert einwandfrei RecyclerView ScrollListener in NestedScrollView .

Vielen Dank


1

Ich musste CoordinatorLayout mit Bildlauf in der Symbolleiste implementieren und es dauerte nur den ganzen Tag, bis ich damit herumgespielt hatte. Ich habe es funktioniert, indem ich NestedScrollView überhaupt entfernt habe. Ich verwende also nur RelativeLayout im Stammverzeichnis.

<?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

Verwenden Sie recyclerView nicht in NestedScrollView. Dies kann zu Kaskadenproblemen führen! Ich schlage vor, ItemViewTypes in RecyclerView für die Verarbeitung mehrerer Arten von Ansichten zu verwenden. Fügen Sie einfach eine RecyclerView mit der Breite und Höhe von match_parent hinzu. Überschreiben Sie dann in Ihrem recyclerViewAdapter getItemViewType und verwenden Sie position, um zu handhaben, welches Layout aufgeblasen werden soll. Danach können Sie Ihren Ansichtshalter mit der onBindViewHolder-Methode behandeln.


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

0

Ich habe diese fantastische Erweiterung verwendet (geschrieben in Kotlin, kann aber auch in Java verwendet werden)

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

Grundsätzlich erhalten Sie das NestedRecyclerViewInnere eines jeden Pakets, sagen wir Utils in Ihrem Projekt, und erstellen dann einfach Ihre Recycling-Ansicht wie

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

Schauen Sie sich diesen großartigen Artikel von Marc Knaup an

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


0

Lösung, um nicht alle untergeordneten Elemente der Recyclingansicht gleichzeitig in der verschachtelten Bildlaufansicht zu laden .

Vorteile:

  1. Laden Sie nicht alle untergeordneten Elemente einmal, wenn Sie die verschachtelte Bildlaufansicht verwenden.
  2. Sie können recycleView.setHasFixedSize (true) für eine bessere Leistung verwenden
  3. Verhindern Sie, dass Webservices alle Daten auf einmal senden. Die Paginierung funktioniert wie erwartet
  4. gut für eine größere Anzahl von Datensätzen.
  5. gut für Geräte mit wenig Speicher
  6. kann weiterhin verschachteltes Scrollen verwenden
  7. Sehr hilfreich, wenn Ihre Recyle-Ansicht komplex ist und viele Ressourcen erfordert.

Fix:

Verwenden Sie in Ihrer XML- Datei anstelle von match_parent oder wrap_content für die Recyclingansicht die feste Höhe .


-5

RecyclerView mit 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" />
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.