Recyclerview di dalam ScrollView tidak menggulir dengan lancar


179

Untuk aplikasi saya, saya menggunakan bagian RecyclerViewdalam ScrollViewyang RecyclerViewmemiliki ketinggian berdasarkan isinya menggunakan perpustakaan ini . Menggulir berfungsi tetapi itu tidak berfungsi dengan baik ketika saya menggulir RecyclerView. Ketika saya menggulir ke atas ScrollViewsendiri itu menggulir dengan lancar.

Kode yang saya gunakan untuk mendefinisikan RecyclerView:

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

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

solusi ini bekerja untuk saya: stackoverflow.com/a/32390370/7308789 terima kasih
Houssin Boulla

1
@tahaDev apa sebenarnya yang tidak berfungsi dalam kasus Anda, tolong uraikan lebih lanjut tentang itu. Selain itu, sepertinya tidak ada solusi yang disediakan untuk Anda, bukan?
Pravin Divraniya

Gunakan androidx.constraintlayout.widget.ConstraintLayoutyang akan menyelesaikan masalah Anda tanpa implementasi yang rumit
Saswata

Jawaban:


379

Coba lakukan:

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

Sebagai alternatif, Anda dapat memodifikasi tata letak menggunakan perpustakaan desain dukungan. Saya kira tata letak Anda saat ini adalah sesuatu seperti:

<ScrollView >
   <LinearLayout >

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

   </LinearLayout >
</ScrollView >

Anda dapat mengubahnya menjadi:

<CoordinatorLayout >

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

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

</CoordinatorLayout >

Namun ini jalan yang lebih panjang untuk diambil, dan jika Anda OK dengan manajer tata letak linier kustom, maka cukup nonaktifkan pengguliran bersarang pada tampilan pendaur ulang.

Edit (4/3/2016)

The v 23.2rilis dari perpustakaan dukungan sekarang termasuk sebuah pabrik “wrap konten” fitur dalam semua standar LayoutManagers. Saya tidak mengujinya, tetapi Anda mungkin harus memilih itu ke perpustakaan yang Anda gunakan.

<ScrollView >
   <LinearLayout >

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

   </LinearLayout >
</ScrollView >

16
Untuk menambah jawaban ini: setNestedScrollingEnabled(false)hanya berfungsi ketika saya mematikan ScrollViewuntuk a NestedScrollView.
Richard Le Mesurier

11
Bagi saya, setNestedScrollingEnabled(false)memberi saya kembali bergulir mulus dengan RecyclerViewbagian dalam saya ScrollView- Terima kasih! Tapi saya masih tidak mengerti mengapa itu berhasil ...? Apa maksudnya mengatur nested scrolling false?
Micro

33
Perhatikan bahwa android:nestedScrollingEnabled="false"hanya berfungsi untuk API 21+ tetapi v.setNestedScrollingEnabled(false)OK untuk <21.
Eric B.

3
Untuk referensi di masa mendatang, jika ada yang mengalami RecyclerViewmasalah wrap_content di dalam ScrollViewyang hanya terjadi pada perangkat marshmallow / nougat (API 23, 24), periksa solusi saya di stackoverflow.com/a/38995399/132121
Hossain Khan

2
Kelemahan dari solusi ini yang saya alami saat ini adalah RecyclerView tidak akan menerima peristiwa di dalamnya onScrollListener. Yang saya butuhkan karena saya ingin mengambil lebih banyak data ketika saya hanya memiliki sejumlah item dalam pendaur ulang
Daniel W.

82

Saya hanya perlu menggunakan ini:

mMyRecyclerView.setNestedScrollingEnabled(false);

di saya onCreateView() metode .

Terima kasih banyak!


26

Anda dapat menggunakan cara ini:

Tambahkan baris ini ke file xml recyclerView Anda:

android:nestedScrollingEnabled="false"

Atau dalam kode java:

RecyclerView.setNestedScrollingEnabled(false);

Semoga ini bisa membantu.


10
membutuhkan Api 21+
Muhammad Riyaz

11

Anda dapat mencoba keduanya dengan XML dan secara terprogram. Tetapi masalah yang mungkin Anda hadapi adalah (di bawah API 21) dengan melakukannya dengan XML tidak akan berfungsi. Jadi lebih baik mengaturnya secara terprogram dalam Aktivitas / Fragmen Anda.

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

Secara terprogram:

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

6

Menggunakan Nested Scroll View alih-alih Scroll View memecahkan masalah saya

<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

Saya memiliki masalah serupa (saya mencoba membuat sesuatu yang mirip RecyclerViews seperti desain Google PlayStore). Cara terbaik untuk mengatasinya adalah dengan mensubclassing anak RecyclerViews dan mengganti metode 'onInterceptTouchEvent' dan 'onTouchEvent'. Dengan cara ini Anda mendapatkan kontrol penuh tentang bagaimana perilaku peristiwa tersebut dan akhirnya bergulir.


3

Mengganti ScrollView dengan NestedScrollView menghasilkan scrolling yang mulus ke bawah.


1

Jika Anda menggunakan VideoView atau widget berat di childviews Anda, simpan RecyclerView Anda dengan ketinggian wrap_content di dalam NestedScrollView dengan ketinggianmatch_parent Kemudian, scrolling akan bekerja semulus yang Anda inginkan.

FYI,

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

Terima kasih, Mikro, ini dari petunjuk Anda!

karthik


1

Ringkasan semua jawaban (Keuntungan & Kerugian)

Untuk single recyclerview

Anda dapat menggunakannya di dalam tata letak Koordinator.

Keuntungan - tidak akan memuat seluruh item recyclerview. Pemuatan jadi mulus.

Kerugian - Anda tidak dapat memuat dua recyclerview di dalam tata letak Koordinator - ini menghasilkan masalah gulir

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

Untuk beberapa tinjauan ulang dengan baris minimum

Anda dapat memuat di dalam NestedScrollView

Keuntungan - itu akan bergulir dengan lancar

Kerugian - Memuat semua baris recyclerview sehingga aktivitas Anda terbuka dengan penundaan

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

Untuk multiple recylerview dengan baris besar (lebih dari 100)

Anda harus pergi dengan recyclerview.

Keuntungan - Gulir dengan lancar, muat dengan lancar

Kerugian - Anda perlu menulis lebih banyak kode dan logika

Muat masing-masing recylerview di dalam recyclerview utama dengan bantuan multi-viewholder

ex:

MainRecyclerview

-ChildRecyclerview1 (ViewHolder1)

-ChildRecyclerview2 (ViewHolder2)

-ChildRecyclerview3 (ViewHolder3) 

-Any other layout   (ViewHolder4)

Referensi untuk multi-viewHolder - https://stackoverflow.com/a/26245463/3879847


0

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

dalam kode java:

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

0

Atau Anda bisa mengatur android:focusableInTouchMode="true"dalam tampilan pendaur ulang Anda


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>

Kode ini berfungsi di Android ConstraintLayout


0

Kotlin

Setel isNestedScrollingEnabledke falseuntuk setiap RecyclerView yang ada di bawah tampilan gulir

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

Menggunakan 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" />
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.