Recyclerview in ScrollView läuft nicht reibungslos


179

Für meine App verwende ich ein RecyclerViewInside A, ScrollViewbei dem RecyclerViewdie Höhe basierend auf dem Inhalt dieser Bibliothek verwendet wird . Das Scrollen funktioniert, aber es funktioniert nicht reibungslos, wenn ich über das Bildlauf scrolle RecyclerView. Wenn ich über das Bild ScrollViewselbst scrolle, läuft es reibungslos.

Der Code, mit dem ich Folgendes definiere RecyclerView:

LinearLayoutManager friendsLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext(), android.support.v7.widget.LinearLayoutManager.VERTICAL, false);
mFriendsListView.setLayoutManager(friendsLayoutManager);
mFriendsListView.addItemDecoration(new DividerItemDecoration(getActivity().getApplicationContext(), null));

Die RecyclerViewin der ScrollView:

<android.support.v7.widget.RecyclerView
    android:layout_marginTop="10dp"
    android:layout_marginBottom="10dp"
    android:id="@+id/friendsList"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

Diese Lösung funktioniert für mich: stackoverflow.com/a/32390370/7308789 danke
Houssin Boulla

1
@tahaDev was genau in Ihrem Fall nicht funktioniert, bitte erläutern Sie mehr dazu. Es scheint auch, dass in Ihrem Fall keine bereitgestellten Lösungen funktioniert haben, oder?
Pravin Divraniya

Verwenden Sie, androidx.constraintlayout.widget.ConstraintLayoutdie Ihr Problem ohne komplexe Implementierungen lösen wird
Saswata

Antworten:


379

Versuchen Sie Folgendes:

RecyclerView v = (RecyclerView) findViewById(...);
v.setNestedScrollingEnabled(false);

Alternativ können Sie Ihr Layout mithilfe der Support-Designbibliothek ändern. Ich denke, Ihr aktuelles Layout ist ungefähr so:

<ScrollView >
   <LinearLayout >

       <View > <!-- upper content -->
       <RecyclerView > <!-- with custom layoutmanager -->

   </LinearLayout >
</ScrollView >

Sie können dies ändern zu:

<CoordinatorLayout >

    <AppBarLayout >
        <CollapsingToolbarLayout >
             <!-- with your content, and layout_scrollFlags="scroll" -->
        </CollapsingToolbarLayout >
    </AppBarLayout >

    <RecyclerView > <!-- with standard layoutManager -->

</CoordinatorLayout >

Dies ist jedoch ein längerer Weg. Wenn Sie mit dem benutzerdefinierten linearen Layout-Manager einverstanden sind, deaktivieren Sie einfach das verschachtelte Scrollen in der Recycler-Ansicht.

Bearbeiten (03.04.2016)

Die v 23.2Veröffentlichung der Support-Bibliotheken enthält jetzt in allen Standardeinstellungen eine werkseitige Funktion zum Umschließen von Inhalten LayoutManager. Ich habe es nicht getestet, aber Sie sollten es wahrscheinlich der Bibliothek vorziehen, die Sie verwendet haben.

<ScrollView >
   <LinearLayout >

       <View > <!-- upper content -->
       <RecyclerView > <!-- with wrap_content -->

   </LinearLayout >
</ScrollView >

16
Um diese Antwort zu ergänzen: setNestedScrollingEnabled(false)funktionierte nur, wenn ich stattdessen die ScrollViewfür a NestedScrollViewausschaltete.
Richard Le Mesurier

11
Für mich setNestedScrollingEnabled(false)gab mir wieder reibungsloses Scrollen mit meiner RecyclerViewInnenseite eines ScrollView- Danke! Aber ich verstehe immer noch nicht, warum das funktioniert ...? Was bedeutet es wirklich, verschachteltes Scrollen auf falsch zu setzen?
Micro

33
Beachten Sie, dass dies android:nestedScrollingEnabled="false"nur für API 21+ funktioniert, v.setNestedScrollingEnabled(false)für <21 jedoch in Ordnung ist.
Eric B.

3
Wenn in Zukunft ein RecyclerViewProblem mit wrap_content auftritt, ScrollViewdas nur auf Marshmallow / Nougat-Geräten (API 23, 24) auftritt
Hossain Khan

2
Ein Nachteil dieser Lösung, die ich gerade erlebe, ist, dass der RecyclerView keine Ereignisse in seinem onScrollListener empfängt. Was ich brauche, weil ich mehr Daten abrufen möchte, wenn ich nur eine bestimmte Anzahl von Artikeln im Recycler habe
Daniel W.

82

Ich musste nur Folgendes verwenden:

mMyRecyclerView.setNestedScrollingEnabled(false);

in meinem onCreateView() Methode.

Vielen Dank!


26

Sie können diesen Weg entweder verwenden:

Fügen Sie diese Zeile Ihrer XML-Datei recyclerView hinzu:

android:nestedScrollingEnabled="false"

Oder im Java-Code:

RecyclerView.setNestedScrollingEnabled(false);

Hoffe das hat geholfen.


10
erfordert Api 21+
Muhammad Riyaz

11

Sie können sowohl mit XML als auch programmgesteuert versuchen. Das Problem, mit dem Sie möglicherweise konfrontiert sind, ist (unter API 21), dass es mit XML nicht funktioniert. Es ist daher besser, es programmgesteuert in Ihrer Aktivität / Ihrem Fragment festzulegen.

XML-Code:

<android.support.v7.widget.RecyclerView
      android:id="@+id/recycleView"
      android:layout_width="match_parent"
      android:visibility="gone"
      android:nestedScrollingEnabled="false"
      android:layout_height="wrap_content"
      android:layout_below="@+id/linearLayoutBottomText" /> 

Programmatisch:

 recycleView = (RecyclerView) findViewById(R.id.recycleView);
 recycleView.setNestedScrollingEnabled(false);

6

Die Verwendung der verschachtelten Bildlaufansicht anstelle der Bildlaufansicht hat mein Problem gelöst

<LinearLayout> <!--Main Layout -->
   <android.support.v4.widget.NestedScrollView>
     <LinearLayout > <!--Nested Scoll View enclosing Layout -->`

       <View > <!-- upper content --> 
       <RecyclerView >


     </LinearLayout > 
   </android.support.v4.widget.NestedScrollView>
</LinearLayout>

5

Ich hatte ähnliche Probleme (ich habe versucht, verschachtelte RecyclerViews wie das Google PlayStore-Design zu erstellen). Der beste Weg, um damit umzugehen, besteht darin, die untergeordneten RecyclerViews in Unterklassen zu unterteilen und die Methoden 'onInterceptTouchEvent' und 'onTouchEvent' zu überschreiben. Auf diese Weise erhalten Sie die vollständige Kontrolle über das Verhalten dieser Ereignisse und können schließlich einen Bildlauf durchführen.


3

Das Ersetzen von ScrollView durch NestedScrollView führte zu einem reibungslosen Bildlauf nach unten.


1

Wenn Sie VideoView oder Widgets mit hohem Gewicht in Ihren untergeordneten Ansichten verwenden, behalten Sie Ihre RecyclerView mit Höhe wrap_content in einer NestedScrollView mit Höhematch_parent Dann funktioniert das Scrollen so perfekt, wie Sie es möchten.

Zu Ihrer Information,

<android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.RecyclerView
            android:layout_width="match_parent"
            android:nestedScrollingEnabled="false"
            android:layout_height="wrap_content"
            android:clipToPadding="false" />

</android.support.v4.widget.NestedScrollView>

Danke Micro das war von deinem Hinweis!

karthik


1

Zusammenfassung aller Antworten (Vor- und Nachteile)

Für einzelne Recyclingansichten

Sie können es im Koordinator-Layout verwenden.

Vorteil - Es werden nicht ganze Recyclerview-Elemente geladen. Also reibungsloses Laden.

Nachteil - Sie können nicht zwei Recycling-Ansichten in das Koordinator-Layout laden - dies führt zu Bildlaufproblemen

Referenz - https://stackoverflow.com/a/33143512/3879847

Für mehrere Wiederholungen mit minimalen Zeilen

Sie können in NestedScrollView laden

Vorteil - es wird reibungslos scrollen

Nachteil - Es werden alle Zeilen der Recycling-Ansicht geladen, sodass Ihre Aktivität mit Verzögerung geöffnet wird

Referenz - https://stackoverflow.com/a/33143512/3879847

Für mehrere Recylerviews mit großen Zeilen (mehr als 100)

Sie müssen mit recyclerview gehen.

Vorteil - Scrollen Sie reibungslos und laden Sie reibungslos

Nachteil - Sie müssen mehr Code und Logik schreiben

Laden Sie jede Recylerview mit Hilfe von Multi-Viewholdern in die Haupt-Recyclerview

Ex:

MainRecyclerview

-ChildRecyclerview1 (ViewHolder1)

-ChildRecyclerview2 (ViewHolder2)

-ChildRecyclerview3 (ViewHolder3) 

-Any other layout   (ViewHolder4)

Referenz für Multi-ViewHolder - https://stackoverflow.com/a/26245463/3879847


0

XML-Code:

<android.support.v4.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <android.support.v7.widget.RecyclerView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:clipToPadding="false" />

        </android.support.v4.widget.NestedScrollView>

im Java-Code:

  recycleView = (RecyclerView) findViewById(R.id.recycleView);
     recycleView.setNestedScrollingEnabled(false);

0

Oder Sie können einfach android:focusableInTouchMode="true"in Ihrer Recycler-Ansicht festlegen


0
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent">

        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent">

            <android.support.constraint.ConstraintLayout
                android:id="@+id/constraintlayout_main"
                android:layout_width="match_parent"
                android:layout_height="@dimen/layout_width_height_fortyfive"
                android:layout_marginLeft="@dimen/padding_margin_sixteen"
                android:layout_marginRight="@dimen/padding_margin_sixteen"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent">

                <TextView
                    android:id="@+id/textview_settings"
                    style="@style/textviewHeaderMain"
                    android:gravity="start"
                    android:text="@string/app_name"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent" />

            </android.support.constraint.ConstraintLayout>

            <android.support.constraint.ConstraintLayout
                android:id="@+id/constraintlayout_recyclerview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="@dimen/padding_margin_zero"
                android:layout_marginTop="@dimen/padding_margin_zero"
                android:layout_marginEnd="@dimen/padding_margin_zero"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/constraintlayout_main">

                <android.support.v7.widget.RecyclerView
                    android:id="@+id/recyclerview_list"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:nestedScrollingEnabled="false"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent" />

            </android.support.constraint.ConstraintLayout>

        </android.support.constraint.ConstraintLayout>

    </android.support.v4.widget.NestedScrollView>

</android.support.constraint.ConstraintLayout>

Dieser Code funktioniert in ConstraintLayout Android


0

Kotlin

Stellen Sie isNestedScrollingEnabledzu falsefür jeden RecyclerView , die unter der Scroll - Ansicht ist ,

val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
recyclerView.isNestedScrollingEnabled = false

Verwenden des XML-Layouts

<android.support.v7.widget.RecyclerView
    android:layout_marginTop="10dp"
    android:layout_marginBottom="10dp"
    android:id="@+id/friendsList"
    android:layout_width="match_parent"
    android:nestedScrollingEnabled="false"
    android:layout_height="wrap_content" />
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.