Recyclerview ภายใน ScrollView ไม่เลื่อนอย่างราบรื่น


179

สำหรับ app ของฉันฉันใช้RecyclerViewภายในScrollViewที่RecyclerViewมีความสูงขึ้นอยู่กับเนื้อหาของการใช้ห้องสมุดนี้ เลื่อนจะทำงาน RecyclerViewแต่ก็ไม่ได้ทำงานได้อย่างราบรื่นเมื่อฉันเลื่อนมากกว่า เมื่อฉันเลื่อนไปที่ScrollViewตัวเองมันจะเลื่อนอย่างราบรื่น

รหัสที่ฉันใช้เพื่อกำหนดRecyclerView:

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

RecyclerViewใน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" />

วิธีนี้ใช้ได้ผลกับฉัน: stackoverflow.com/a/32390370/7308789ขอบคุณ
Houssin Boulla

1
@tahaDev สิ่งที่ไม่ทำงานในกรณีของคุณโปรดอธิบายเพิ่มเติมเกี่ยวกับที่ นอกจากนี้ดูเหมือนว่าจะไม่มีวิธีแก้ปัญหาที่ให้ในกรณีของคุณใช่ไหม?
Pravin Divraniya

ใช้androidx.constraintlayout.widget.ConstraintLayoutซึ่งจะแก้ปัญหาของคุณได้โดยไม่ต้องใช้งานที่ซับซ้อน
5459

คำตอบ:


379

ลองทำ:

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

คุณสามารถแก้ไขเลย์เอาต์ของคุณโดยใช้ไลบรารี่ออกแบบสนับสนุน ฉันเดาว่าเค้าโครงปัจจุบันของคุณเป็นอย่างไร:

<ScrollView >
   <LinearLayout >

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

   </LinearLayout >
</ScrollView >

คุณสามารถแก้ไขสิ่งนั้นเป็น:

<CoordinatorLayout >

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

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

</CoordinatorLayout >

อย่างไรก็ตามนี่เป็นถนนที่ต้องใช้เวลานานกว่าและหากคุณตกลงกับผู้จัดการเลย์เอาต์แบบเส้นตรงที่กำหนดเองให้ปิดการเลื่อนแบบซ้อนในมุมมองของตัวรีไซเคิล

แก้ไข (4/3/2559)

v 23.2ปล่อยของห้องสมุดการสนับสนุนในขณะนี้มีโรงงาน“ห่อเนื้อหา” ในทุกเริ่มต้นLayoutManagers ฉันไม่ได้ทดสอบมัน แต่คุณน่าจะชอบมันมากกว่าที่ห้องสมุดที่คุณใช้อยู่

<ScrollView >
   <LinearLayout >

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

   </LinearLayout >
</ScrollView >

16
หากต้องการเพิ่มในคำตอบนี้setNestedScrollingEnabled(false)จะทำงานเมื่อฉันเปลี่ยนScrollViewเป็น a NestedScrollViewแทนเท่านั้น
Richard Le Mesurier

11
สำหรับฉันsetNestedScrollingEnabled(false)ให้ฉันเลื่อนกลับอย่างราบรื่นด้วยRecyclerViewภายในของฉันScrollView- ขอบคุณ! แต่ฉันก็ยังไม่เข้าใจว่าทำไมถึงใช้งานได้ ... การตั้งค่าการเลื่อนแบบซ้อนที่แท้จริงหมายถึงอะไร
Micro

33
โปรดทราบว่าandroid:nestedScrollingEnabled="false"ใช้งานได้กับ API 21+ เท่านั้น แต่v.setNestedScrollingEnabled(false)ใช้ได้สำหรับ <21
Eric B.

3
สำหรับการอ้างอิงในอนาคตหากใครกำลังประสบRecyclerViewปัญหา wrap_content ภายในScrollViewที่เกิดขึ้นเฉพาะกับอุปกรณ์ marshmallow / nougat (API 23, 24) ให้ตรวจสอบวิธีแก้ปัญหาของฉันที่stackoverflow.com/a/38995399/132121
Hossain Khan

2
ข้อเสียของวิธีแก้ปัญหาที่ฉันกำลังประสบอยู่ในตอนนี้คือ RecyclerView จะไม่ได้รับเหตุการณ์ที่อยู่ในScrollListener ซึ่งฉันต้องการเพราะฉันต้องการดึงข้อมูลเพิ่มเติมเมื่อฉันมีรายการจำนวนหนึ่งในผู้รีไซเคิลเท่านั้น
Daniel W.


26

คุณสามารถใช้วิธีนี้:

เพิ่มบรรทัดนี้ลงในไฟล์ recyclerView xml ของคุณ:

android:nestedScrollingEnabled="false"

หรือในรหัส java:

RecyclerView.setNestedScrollingEnabled(false);

หวังว่านี่จะช่วยได้


10
ต้องการ Api 21+
Muhammad Riyaz

11

คุณสามารถลองด้วยวิธีทั้งกับ XML และโดยทางโปรแกรม แต่ปัญหาที่คุณอาจพบคือ (ด้านล่าง API 21) ด้วยการทำกับ XML จะไม่ทำงาน ดังนั้นจึงเป็นการดีกว่าถ้าคุณตั้งโปรแกรมไว้ในกิจกรรม / ชิ้นส่วนของคุณ

รหัส 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" /> 

โปรแกรม:

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

6

การใช้มุมมองเลื่อนซ้อนแทนมุมมองเลื่อนแก้ไขปัญหาของฉัน

<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

ฉันมีปัญหาที่คล้ายกัน (ฉันพยายามสร้าง Recycler รีวิวหลาย ๆ อย่างเช่นการออกแบบ Google PlayStore) วิธีที่ดีที่สุดในการจัดการกับเรื่องนี้คือการ subclassing เด็ก RecyclerViews และเอาชนะ 'onInterceptTouchEvent' และ 'onTouchEvent' วิธีนี้คุณจะได้รับการควบคุมอย่างสมบูรณ์ว่ากิจกรรมเหล่านั้นทำงานอย่างไรและในที่สุดการเลื่อน


3

การแทนที่ ScrollView ด้วย NestedScrollView ทำให้การเลื่อนไปด้านล่างราบรื่น


1

หากคุณใช้ VideoView หรือวิดเจ็ตที่มีน้ำหนักมากใน childviews ของคุณให้ RecyclerView ของคุณมีความสูงwrap_content ภายใน NestedScrollView ที่มีความสูงmatch_parent จากนั้นการเลื่อนจะทำงานได้อย่างราบรื่นตามที่คุณต้องการ

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>

ขอบคุณ Micro นี่มาจากคำใบ้ของคุณ!

คาร์ทิค


1

สรุปคำตอบทั้งหมด (ข้อดี & ข้อเสีย)

สำหรับมุมมองรีไซเคิล

คุณสามารถใช้ภายในเลย์เอาต์ของผู้ประสานงาน

ข้อได้เปรียบ - มันจะไม่โหลดรายการรีไซเคิลทั้งหมด โหลดราบรื่นมาก

ข้อเสีย - คุณไม่สามารถโหลดสองมุมมองรีไซเคิลภายในเค้าโครงผู้ประสานงาน - สร้างปัญหาการเลื่อน

การอ้างอิง - https://stackoverflow.com/a/33143512/3879847

สำหรับหลายมุมมองพร้อมแถวต่ำสุด

คุณสามารถโหลดภายใน NestedScrollView

ข้อได้เปรียบ - มันจะเลื่อนอย่างราบรื่น

ข้อเสีย - จะโหลด recyclerview ทุกแถวเพื่อให้กิจกรรมของคุณเปิดได้ล่าช้า

การอ้างอิง - https://stackoverflow.com/a/33143512/3879847

สำหรับ recylerview ที่มีแถวขนาดใหญ่ (มากกว่า 100)

คุณต้องไปกับ recyclerview

ข้อได้เปรียบ - เลื่อนอย่างราบรื่นโหลดอย่างราบรื่น

ข้อเสีย - คุณต้องเขียนโค้ดและตรรกะเพิ่มเติม

โหลดแต่ละมุมมองภายใน recyclerview หลักด้วยความช่วยเหลือของผู้ถือหลายมุมมอง

อดีต:

MainRecyclerview

-ChildRecyclerview1 (ViewHolder1)

-ChildRecyclerview2 (ViewHolder2)

-ChildRecyclerview3 (ViewHolder3) 

-Any other layout   (ViewHolder4)

การอ้างอิงสำหรับ multi-viewHolder - https://stackoverflow.com/a/26245463/3879847


0

รหัส 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>

ในรหัส java:

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


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>

รหัสนี้ใช้สำหรับ Android ConstraintLayout


0

Kotlin

ตั้งค่าisNestedScrollingEnabledเป็นfalseสำหรับทุก RecyclerView ที่อยู่ภายใต้มุมมองการเลื่อน

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

ใช้เค้าโครง 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" />
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.