Recyclerview all'interno di ScrollView non scorre uniformemente


179

Per la mia app sto usando un RecyclerViewinterno a ScrollViewdove RecyclerViewha un'altezza basata sul suo contenuto usando questa libreria . Lo scorrimento funziona ma non funziona senza problemi quando scorro il RecyclerView. Quando scorro su ScrollViewse stesso, scorre senza intoppi.

Il codice che sto usando per definire RecyclerView:

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

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

questa soluzione funziona per me: stackoverflow.com/a/32390370/7308789 grazie
Houssin Boulla

1
@tahaDev cosa non funziona esattamente nel tuo caso, ti preghiamo di approfondire. Inoltre, sembra che nessuna soluzione fornita abbia funzionato nel tuo caso, vero?
Pravin Divraniya,

Utilizzalo androidx.constraintlayout.widget.ConstraintLayoutper risolvere il tuo problema senza implementazioni complesse
Saswata,

Risposte:


379

Prova a fare:

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

In alternativa, è possibile modificare il layout utilizzando la libreria di progettazione di supporto. Immagino che il tuo layout attuale sia qualcosa del tipo:

<ScrollView >
   <LinearLayout >

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

   </LinearLayout >
</ScrollView >

Puoi modificarlo per:

<CoordinatorLayout >

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

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

</CoordinatorLayout >

Tuttavia, questa è una strada più lunga da percorrere e, se si è d'accordo con il gestore del layout lineare personalizzato, è sufficiente disabilitare lo scorrimento nidificato nella vista Riciclatore.

Modifica (4/3/2016)

Il v 23.2rilascio delle librerie di supporto ora include una funzionalità di "contenuto a capo" di fabbrica in tutti i messaggi predefiniti LayoutManager. Non l'ho provato, ma probabilmente dovresti preferirlo alla libreria che stavi usando.

<ScrollView >
   <LinearLayout >

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

   </LinearLayout >
</ScrollView >

16
Per aggiungere a questa risposta: ha setNestedScrollingEnabled(false)funzionato solo quando ho cambiato il ScrollViewfor a NestedScrollViewinvece.
Richard Le Mesurier,

11
Per quanto mi riguarda, setNestedScrollingEnabled(false)mi ha restituito uno scorrimento uniforme con l' RecyclerViewinterno di un ScrollView- Grazie! Ma ancora non capisco perché funzioni ...? Cosa significa veramente impostare lo scorrimento nidificato falso?
Micro

33
Nota che android:nestedScrollingEnabled="false"funziona solo per API 21+ ma v.setNestedScrollingEnabled(false)è OK per <21.
Eric B.

3
Per riferimento futuro, se qualcuno sta riscontrando RecyclerViewun problema con wrap_content all'interno ScrollViewche si verifica solo su dispositivi marshmallow / nougat (API 23, 24), controlla la mia soluzione alternativa su stackoverflow.com/a/38995399/132121
Hossain Khan,

2
Un aspetto negativo di questa soluzione che sto sperimentando in questo momento è che RecyclerView non riceverà eventi in onScrollListener. Di cui ho bisogno perché voglio recuperare più dati quando ho solo un certo numero di articoli nel riciclatore
Daniel W.

82

Avevo solo bisogno di usare questo:

mMyRecyclerView.setNestedScrollingEnabled(false);

nel mio onCreateView()metodo.

Molte grazie!


26

Puoi usare in questo modo:

Aggiungi questa riga al tuo file xml di recyclerView:

android:nestedScrollingEnabled="false"

O nel codice java:

RecyclerView.setNestedScrollingEnabled(false);

Spero che questo abbia aiutato.


10
richiede Api 21+
Muhammad Riyaz,

11

Puoi provare in entrambi i modi con XML e programmaticamente. Ma il problema che potresti incontrare è (sotto API 21) farlo con XML non funzionerà. Quindi è meglio impostarlo a livello di programmazione in Attività / Frammento.

Codice XML:

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

livello di programmazione:

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

6

L'uso della vista di scorrimento nidificata anziché della vista di scorrimento ha risolto il mio problema

<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

Ho avuto problemi simili (ho provato a creare un RecyclerViews nidificato qualcosa come il design di Google PlayStore). Il modo migliore per risolvere questo problema è la sottoclasse delle visualizzazioni Recycler figlio e l'override dei metodi "onInterceptTouchEvent" e "onTouchEvent". In questo modo si ottiene il controllo completo su come si comportano quegli eventi e infine lo scorrimento.


3

La sostituzione di ScrollView con NestedScrollView ha comportato uno scorrimento regolare verso il basso.


1

Se stai usando VideoView o widget pesanti nelle tue visualizzazioni figlio, mantieni il tuo RecyclerView con l'altezza wrap_content all'interno di un NestedScrollView con l'altezza. match_parent Quindi lo scorrimento funzionerà perfettamente come desideri.

Cordiali saluti,

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

Grazie Micro questo è stato dal tuo suggerimento!

Karthik


1

Riepilogo di tutte le risposte (Vantaggi e svantaggi)

Per singolo riciclo

puoi usarlo nel layout di Coordinator.

Vantaggio : non caricherà interi articoli recyclerview. Caricamento così regolare.

Svantaggio : non è possibile caricare due recyclerview all'interno del layout di Coordinator, poiché produce problemi di scorrimento

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

Per recylerview multiplo con righe minime

puoi caricare all'interno di NestedScrollView

Vantaggio : scorre senza intoppi

Svantaggio : carica tutte le righe di recyclerview in modo che l'attività si apra con ritardo

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

Per recylerview multipli con file di grandi dimensioni (oltre 100)

Devi andare con recyclerview.

Vantaggio : scorrere senza intoppi, caricare senza problemi

Svantaggio : è necessario scrivere più codice e logica

Carica ogni recylerview all'interno del recyclerview principale con l'aiuto di multi-viewholder

ex:

MainRecyclerview

-ChildRecyclerview1 (ViewHolder1)

-ChildRecyclerview2 (ViewHolder2)

-ChildRecyclerview3 (ViewHolder3) 

-Any other layout   (ViewHolder4)

Riferimento per multi-viewHolder - https://stackoverflow.com/a/26245463/3879847


0

Codice XML:

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

nel codice java:

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

0

Oppure puoi semplicemente impostare android:focusableInTouchMode="true"la vista del tuo riciclatore


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>

Questo codice funziona con ConstraintLayout Android


0

Kotlin

Impostare isNestedScrollingEnabledsu falseper ogni RecyclerView sotto la vista a scorrimento

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

Utilizzo del layout XML

<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" />
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.