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.