Làm cách nào để sử dụng RecyclerView bên trong NestedScrollView?


210

Làm thế nào để sử dụng RecyclerViewbên trong NestedScrollView? RecyclerViewnội dung không hiển thị sau khi cài đặt bộ điều hợp.

CẬP NHẬT mã bố cục cập nhật.

<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="@dimen/keyline_1">

    </RelativeLayout>

    <View
        android:id="@+id/separator"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#e5e5e5" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/conversation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

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


@Mecid Không có lý do để sử dụng RecyclerView bên trong ScrollView (hoặc NestedScrollView).
Gabriele Mariotti

2
@Mecid bạn không bao giờ nên đặt chế độ xem có thể cuộn trong chế độ xem có thể cuộn khác. Đó là một quy tắc chung trong Android.
Gabriele Mariotti

6
@GabrieleMariotti tôi biết quy tắc này, nhưng NestedScrollView đã phát triển để khắc phục vấn đề này.
Mecid

1
Nó không đúng. NestedScrollView giống như ScrollView, nhưng nó hỗ trợ hoạt động như cả cha mẹ và con cuộn cuộn lồng nhau. Trong trường hợp của bạn, bạn phải xác định hành vi cuộn của riêng bạn.
Gabriele Mariotti

Câu trả lời:


216

Thay thế recyclerView của bạn bằng,

<android.support.v7.widget.RecyclerView
    android:id="@+id/conversation"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

đây,

app:layout_behavior="@string/appbar_scrolling_view_behavior"

sẽ quản lý phần còn lại của mọi thứ.

Một điều nữa, không cần phải đặt recyclerView của bạn bên trong NestedScrollView


33
Tôi không thể hiểu tại sao giải pháp này không nhận được nhiều phiếu bầu nhất. Nó không đạt được NestedScrollViewnhưng chỉ với app:layout_behavior="@string/appbar_scrolling_view_behavior". Đây là chìa khóa!
hata

3
@RahulUpadhyay điều này hiệu quả với tôi, nhưng tôi nghĩ rằng dòng cuối cùng của bạn là sai, RecyclerView hoàn toàn không hiển thị nếu nó nằm trong NestedScrollView. Tuy nhiên, bạn là một siêu sao: D
Leon

3
Nó hoạt động! chỉ cần cập nhật thư viện recyclerview biên dịch 'com.android.support:recyclerview-v7:+'
Fabio Guerra

28
Giải pháp này được thiết kế để được sử dụng với CoordinatorLayout, AppBarLayoutvà thích hợp đặt layout_scrollFlagstrên quan điểm con (s) mà nên được cuộn với RecyclerView. Không chắc chắn tại sao điều này đã được bỏ qua từ câu trả lời. Nếu không, đây là một giải pháp tốt đẹp và đơn giản.
Sanvywell

9
Tôi nghĩ rằng điều rất quan trọng là phải hiểu rằng RecyclerView đang TUYỂN DỤNG KHÔNG LÀM VIỆC ở đây. Kết quả là, nếu bạn có một danh sách dài các mục, nó sẽ xuất hiện với sự đóng băng UI đáng chú ý.
Gaket

121

CẬP NHẬT 1

Vì Thư viện hỗ trợ Android 23.2.0, đã có thêm phương thức setAutoMeasureEnabled(true)cho Trình quản lý bố cục. Nó làm cho RecyclerView bao bọc nội dung của nó và hoạt động như một bùa mê.
http://android-developers.blogspot.ru/2016/02/android-support-l Library-232.html

Vì vậy, chỉ cần thêm một cái gì đó như thế này:

    LayoutManager layoutManager = new LinearLayoutManager(this);
    layoutManager.setAutoMeasureEnabled(true);
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setNestedScrollingEnabled(false);


CẬP NHẬT 2

Do 27.1.0 setAutoMeasureEnabledkhông được dùng nữa, do đó bạn nên cung cấp triển khai tùy chỉnh Trình quản lý bố cục với phương thức ghi đèisAutoMeasureEnabled()

Nhưng sau nhiều trường hợp sử dụng RecyclerView, tôi thực sự khuyên bạn không nên sử dụng nó trong chế độ gói , vì đây không phải là mục đích của nó. Cố gắng cấu trúc lại toàn bộ bố cục của bạn bằng cách sử dụng RecyclerView đơn thông thường với nhiều loại mục. Hoặc sử dụng phương pháp tiếp cận với linearLayout mà tôi mô tả bên dưới như là phương sách cuối cùng


Câu trả lời cũ (không nên dùng)

Bạn có thể sử dụng RecyclerViewbên trong NestedScrollView. Trước hết bạn nên thực hiện tùy chỉnh của riêng bạn LinearLayoutManager, nó làm cho bạn RecyclerViewbọc nội dung của nó. Ví dụ:

public class WrappingLinearLayoutManager extends LinearLayoutManager
{

    public WrappingLinearLayoutManager(Context context) {
        super(context);
    }

    private int[] mMeasuredDimension = new int[2];

    @Override
    public boolean canScrollVertically() {
        return false;
    }

    @Override
    public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state,
            int widthSpec, int heightSpec) {
        final int widthMode = View.MeasureSpec.getMode(widthSpec);
        final int heightMode = View.MeasureSpec.getMode(heightSpec);

        final int widthSize = View.MeasureSpec.getSize(widthSpec);
        final int heightSize = View.MeasureSpec.getSize(heightSpec);

        int width = 0;
        int height = 0;
        for (int i = 0; i < getItemCount(); i++) {
            if (getOrientation() == HORIZONTAL) {
                measureScrapChild(recycler, i,
                        View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                        heightSpec,
                        mMeasuredDimension);

                width = width + mMeasuredDimension[0];
                if (i == 0) {
                    height = mMeasuredDimension[1];
                }
            } else {
                measureScrapChild(recycler, i,
                        widthSpec,
                        View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                        mMeasuredDimension);

                height = height + mMeasuredDimension[1];
                if (i == 0) {
                    width = mMeasuredDimension[0];
                }
            }
        }

        switch (widthMode) {
            case View.MeasureSpec.EXACTLY:
                width = widthSize;
            case View.MeasureSpec.AT_MOST:
            case View.MeasureSpec.UNSPECIFIED:
        }

        switch (heightMode) {
            case View.MeasureSpec.EXACTLY:
                height = heightSize;
            case View.MeasureSpec.AT_MOST:
            case View.MeasureSpec.UNSPECIFIED:
        }

        setMeasuredDimension(width, height);
    }

    private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
            int heightSpec, int[] measuredDimension) {

        View view = recycler.getViewForPosition(position);
        if (view.getVisibility() == View.GONE) {
            measuredDimension[0] = 0;
            measuredDimension[1] = 0;
            return;
        }
        // For adding Item Decor Insets to view
        super.measureChildWithMargins(view, 0, 0);
        RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
        int childWidthSpec = ViewGroup.getChildMeasureSpec(
                widthSpec,
                getPaddingLeft() + getPaddingRight() + getDecoratedLeft(view) + getDecoratedRight(view),
                p.width);
        int childHeightSpec = ViewGroup.getChildMeasureSpec(
                heightSpec,
                getPaddingTop() + getPaddingBottom() + getDecoratedTop(view) + getDecoratedBottom(view),
                p.height);
        view.measure(childWidthSpec, childHeightSpec);

        // Get decorated measurements
        measuredDimension[0] = getDecoratedMeasuredWidth(view) + p.leftMargin + p.rightMargin;
        measuredDimension[1] = getDecoratedMeasuredHeight(view) + p.bottomMargin + p.topMargin;
        recycler.recycleView(view);
    }
}

Sau đó sử dụng cái này LayoutManagercho bạnRecyclerView

recyclerView.setLayoutManager(new WrappingLinearLayoutManager(getContext()));

Nhưng bạn cũng nên gọi hai phương thức đó:

recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(false);

Ở đây setNestedScrollingEnabled(false)vô hiệu hóa cuộn cho RecyclerView, vì vậy nó không chặn sự kiện cuộn từ NestedScrollView. Và setHasFixedSize(false)xác định rằng những thay đổi trong nội dung bộ điều hợp có thể thay đổi kích thước củaRecyclerView

Lưu ý quan trọng: Giải pháp này có chút lỗi trong một số trường hợp và có vấn đề với độ hoàn hảo, vì vậy nếu bạn có nhiều mục trong thì RecyclerViewtôi khuyên bạn nên sử dụng LinearLayouttriển khai danh sách dựa trên tùy chỉnh , tạo tương tự Bộ điều hợp cho nó và làm cho nó cư xử như ListViewhayRecyclerView


19
Chú ý! Đừng sử dụng cái này nếu bạn có nhiều đồ trong đó RecyclerView.
Brais Gabin

1
@BraisGabin, bạn đã đúng: setHasFixedSize (false) gây ra nhiều lần làm mới RecyclerView, vì vậy nếu nó có nhiều mục, nó sẽ hoạt động rất chậm. Trong những trường hợp đó, tôi sử dụng linearLayout với một loại "bộ điều hợp" tùy chỉnh cho nó để khiến nó hoạt động như ListView hoặc RecyclerView
smbd uknow

1
Cảm ơn rất nhiều! Tiết kiệm cho tôi hàng giờ. Nhân tiện, trang trí vật phẩm cuối cùng không được hiển thị với trình quản lý bố cục này (và chỉ với cái này), có thể xảy ra lỗi không?
Jjang

2
setAutoMeasureEnables không được chấp nhận ở cấp API 27.1.0 developer.android.com/reference/android/support/v7/widget/
Dika

2
thay vào đó, ghi đè boolean làAutoMeasureEnables (). nó Trả về việc đo thông qua bố cục có nên sử dụng cơ chế AutoMeasure của RecyclerView hay không nếu nó được thực hiện bằng cách triển khai onMeasure của Trình quản lý bố cục (Recycler, State, int, int). Phương thức này trả về false theo mặc định (nó thực sự trả về giá trị được truyền cho tập không được chấp nhậnAutoMeasureEnables (boolean)) và nên được ghi đè để trả về true nếu Trình quản lý bố cục muốn được tự động đo bởi RecyclerView. Nếu phương thức này bị ghi đè để trả về true, onMeasure (Recycler, State, int, int) không nên bị ghi đè.
Peterstev Uremgba

100

1) Bạn cần sử dụng thư viện hỗ trợ 23.2.0 (hoặc) ở trên

2) và RecyclerViewchiều cao sẽ là wrap_content.

3) recyclerView.setNestedScrollingEnabled(false)

Nhưng bằng cách này, mô hình tái chế không hoạt động . (tức là tất cả các chế độ xem sẽ được tải cùng một lúcwrap_contentcần chiều cao hoàn thành, RecyclerViewvì vậy nó sẽ thu hút tất cả các Views at once. No view will be recycled). Try not to use this pattern unless it is really required. Try to usekhung nhìn conType and add all other views that need to scroll toRecyclerView rather than usingRecyclerView inScrollview`. Tác động hiệu suất sẽ rất cao.

Để làm cho nó đơn giản "nó chỉ hoạt động như LinearLayoutvới tất cả các quan điểm trẻ em"


6
Cảm ơn @Ashok. Cài đặt recyclerView.setNestedScrollingEnabled(false)giúp tôi có một cuộn trơn tru.
Shubhral

3
Đây phải là câu trả lời được chấp nhận! bởi vì nó cũng chỉ ra rằng Không có chế độ xem nào sẽ được tái chế và tất cả các chế độ xem sẽ được rút ra cùng một lúc.
M'hamed

3
@AshokVarma, vấn đề tương tự tôi đang phải đối mặt bây giờ. nhưng cuộn hoạt động tốt trong recyclerView nhưng tôi không thể thực hiện cuộn Endless cho recyclerview beacuse tất cả các chế độ xem của recyclerview cùng một lúc để nó tiếp tục gọi dịch vụ web. Vì vậy, làm thế nào tôi có thể xử lý này?
Anantha Babu

@AnanthaBabu thay vì sử dụng recyclerview trong chế độ xem cuộn. chuyển đổi tất cả các mục trong scrollview thành các mục trong chế độ xem tái chế. bạn có thể sử dụng kiểu xem tái chế và vẽ các loại bố cục khác nhau. Có một số thư viện tốt để xử lý cả những điều này (Sử dụng các thư viện nếu bạn có cấu trúc khung nhìn thực sự phức tạp và nếu bạn muốn các thành phần có thể tái sử dụng).
Ashok Varma

1
@AshokVarma có giải pháp nào cho vấn đề hành vi tái chế không? Tôi không muốn recyclerview vẽ tất cả bọn trẻ trong một lần bắn.
andro-girl

36

Bạn có thể sử dụng android:fillViewport="true"để thực hiện các NestedScrollViewbiện pháp RecyclerView. Các RecyclerViewsẽ điền chiều cao còn lại. vì vậy nếu bạn muốn di chuyển các NestScrollView, bạn có thể thiết lập RecyclerView's minHeight.


14
nếu bạn có một bộ tái chế gồm 200 mục và bạn làm điều này, thì Nestedscrollview sẽ mở rộng để lấp đầy toàn bộ 200 mục!
RJFares

1
@RJFares Điều đó không bao giờ xảy ra. Tôi thử bản demo và sử dụng LayoutInspector để kiểm tra bố cục, nó chỉ hoạt động tốt. Bạn có thể cung cấp các phiên bản recyclerView của bạn?
zayn

26

Đơn giản chỉ cần thêm recyclerView.setNestedScrollingEnabled(false);trước khi setAdapternó làm việc cho tôi. Tôi đã không thêm app:layout_behavior="@string/appbar_scrolling_view_behavior"bất cứ nơi nào và không đặt bất kỳ trình quản lý bố cục tùy chỉnh nào

<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="15dp"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/white"
                android:text="Some Text..."
                android:padding="15dp" />

        </LinearLayout>

        <LinearLayout
            android:orientation="vertical"
            android:padding="15dp"
            android:layout_marginTop="10dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Quick Links"
                android:textColor="@color/black"
                android:textStyle="bold"
                android:textAllCaps="true"
                android:paddingLeft="20dp"
                android:drawableLeft="@drawable/ic_trending_up_black_24dp"
                android:drawablePadding="10dp"
                android:layout_marginBottom="10dp"
                android:textSize="16sp"/>

            <View
                android:layout_width="fill_parent"
                android:layout_height="1dp"
                android:background="#efefef"/>

            <android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/recyclerview"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </LinearLayout>

    </LinearLayout>

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

10
Nhưng bây giờ nó không tái chế lượt xem nữa?
Đánh dấu Buikema

Không, nó sẽ tái chế, phải không?
Vignesh Sundar

6
không, tôi đã thử với một bố cục rất phức tạp với 200 mục mà Nestedscrollview chỉ mở rộng theo kích thước của các con của nó để nó sẽ mở rộng, do đó, không có sự tái chế nào xảy ra @MarkBuikema bạn có tìm được giải pháp tốt hơn không?
RJFares

20

Đây là những gì làm việc cho tôi

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.v4.widget.NestedScrollView>

4
Bạn có thể xóa ứng dụng thứ hai : layout_behavior = "@ string / appbar_scrolling_view_behavior" Vì hành vi chỉ hoạt động đối với trẻ em trực tiếp của Điều phối viên.
Pepster 16/8/2016

2
Ngoài ra, điều quan trọng là phải đề cập rằng bạn nên có bố trí Điều phối viên làm bố cục gốc. Điều đó không phải lúc nào cũng đúng.
Gaket

10

Có một mã đơn giản và thử nghiệm bạn có thể kiểm tra

<android.support.v4.widget.NestedScrollView
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:fillViewport="true"
     app:layout_behavior="@string/appbar_scrolling_view_behavior">
    <android.support.v7.widget.RecyclerView
           android:layout_width="match_parent"
           android:layout_height="match_parent"/>
   </android.support.v4.widget.NestedScrollView>

9

Đối với androidxnó được gọi là androidx.core.widget.NestedScrollView- và nó cũng cuộn bơ giống nhau với các thuộc tính isScrollContainermeasureAllChildrenđược bật:

<!-- Scrolling Content -->
<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"

    android:isScrollContainer="true"
    android:measureAllChildren="true"

    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fastScrollEnabled="true"
        android:scrollbarStyle="insideInset"
        android:scrollbars="vertical"
        android:splitMotionEvents="false"
        android:verticalScrollbarPosition="right"/>

</androidx.core.widget.NestedScrollView>

7

Hãy thử sử dụng thư viện này - https://github.com/serso/android-linear-layout-manager .

LayoutManager của thư viện làm cho RecyclerView bao bọc nội dung của nó. Trong trường hợp này, RecyclerView sẽ "lớn như các khung nhìn bên trong", do đó, nó sẽ không có thanh cuộn và người dùng sẽ sử dụng các khả năng cuộn của NestedScrollView. Do đó, nó sẽ không mơ hồ như "có thể cuộn bên trong có thể cuộn".


1
Đây là lớp học của LinearLayoutManager từ thư viện này: github.com/serso/android-linear-layout-manager/blob/master/lib/...
Ninja Mã hóa

6

Đây là mã mà tôi đang sử dụng để tránh các sự cố cuộn:

mRecyclerView = (RecyclerView) view.findViewById(android.R.id.list);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mRecyclerView.getLayoutManager().setAutoMeasureEnabled(true);
mRecyclerView.setNestedScrollingEnabled(false);
mRecyclerView.setHasFixedSize(false);

6

Tôi đã sử dụng RecyclerView bên trong NestedScrollView và nó hoạt động với tôi. Điều duy nhất tôi phải ghi nhớ là NestedScrollView chỉ có một chế độ xem con. Vì vậy, trong trường hợp của tôi, tôi đã sử dụng nhóm xem LienearLayout, nơi chứa RecyclerView của tôi cộng với một số khung nhìn khác mà tôi cần.

Tôi gặp một vấn đề khi đặt RecyclerView của mình bên trong NestedScrollView. Tôi nhận ra rằng việc cuộn nội dung của RecyclerView bị chùng xuống.

Sau đó tôi nhận ra rằng RecyclerView của tôi đã nhận được sự kiện cuộn và do đó mâu thuẫn với hành vi cuộn của NestedScrollView.

Vì vậy, để giải quyết vấn đề đó, tôi đã phải vô hiệu hóa chức năng cuộn của RecyclerView bằng phương pháp này movieListNewRecyclerView.setNestedScrollingEnabled(false);

Bạn có thể kiểm tra Instagram của tôi để xem một đoạn video ngắn về những gì tôi thực sự đã làm. Đây là xử lý instagram của tôi ofelix03

Nhấp vào hình ảnh này để xem những gì tôi đã làm


5

Tôi có Viewpager và RecyclerView bên trong NestedScrollView. Sau khi thêm dòng dưới đây

recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(false);

Tôi đã giải quyết vấn đề chậm cuộn và cuộn lag.


3
Ý bạn là recyclerView.setHasFixedSize(true);sao?
Keno Clayton

3

Bạn không thể sử dụng chế độ xem tái chế trong chế độ xem cuộn lồng nhau. Nó không có ý định chứa các chế độ xem có thể cuộn thêm nhưng vì nó là một phần của bố cục cuộn mà bạn cần chế độ xem cuộn lồng nhau. Tôi đã có cùng một vấn đề nhưng cuối cùng tôi đã chuyển văn bản của mình thành một headerview trong recyclerview, biến recyclerview thành một con trực tiếp của bố trí điều phối viên và xóa chế độ xem cuộn lồng nhau. Sau đó, tất cả các vấn đề của tôi đã biến mất.


8
RecyclerViewthực hiện NestedScrollingChild, RecyclerViewnên có thể được cuộn qua NestedScrollView.
Benjamin

Tôi chỉ bỏ phiếu để từ chối stackoverflow.com/review/suggested-edits/9907622 hoàn toàn dựa trên các lỗi tiếng Anh, nhưng có thể có nội dung về giá trị trong đó - bất kỳ ai đi ngang với kiến ​​thức về vấn đề này nên xem và xem chúng có phải không có thể làm sạch nó Nếu không có gì hữu ích ở đó, hãy gắn cờ nhận xét này của tôi để xóa bởi các mod.
Đánh dấu Amery

3

Nếu bạn đang sử dụng RecyclerView-23.2.1hoặc sau này. Giải pháp sau đây sẽ hoạt động tốt:

Trong bố cục của bạn, thêm RecyclerView như thế này:

<android.support.v7.widget.RecyclerView
        android:id="@+id/review_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical" />

Và trong tệp java của bạn:

RecyclerView mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager=new LinearLayoutManager(getContext());
layoutManager.setAutoMeasureEnabled(true);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setAdapter(new YourListAdapter(getContext()));

Ở đây layoutManager.setAutoMeasureEnabled(true);sẽ thực hiện các mẹo.

Kiểm tra vấn đề nàyblog nhà phát triển này để biết thêm thông tin.


Hãy cẩn thận khi sử dụng "mRecyclerView.setHasFixedSize (true);" Tuy nhiên. Bạn chỉ có thể sử dụng nó nếu bạn không thêm hoặc xóa các mục khỏi chế độ xem tái chế khi chạy.
Gaket

2

Một giải pháp để giữ tính năng tái chế của recyclerview và tránh recyclerview để tải tất cả dữ liệu của bạn là thiết lập một chiều cao cố định trong chính recyclerview. Bằng cách này, recyclerview chỉ giới hạn tải tối đa chiều cao của nó có thể hiển thị cho người dùng do đó tái chế phần tử của nó nếu bạn cuộn xuống dưới cùng / trên cùng.


2

Có rất nhiều câu trả lời hay. Điều quan trọng là bạn phải đặt nestedScrollingEnabledthành false. Như đã đề cập ở trên, bạn có thể làm điều đó trong mã java:

mRecyclerView.setNestedScrollingEnabled(false);

Nhưng bạn cũng có cơ hội đặt cùng một thuộc tính trong mã xml ( android:nestedScrollingEnabled="false"):

 <android.support.v7.widget.RecyclerView
 android:id="@+id/recyclerview"
 android:nestedScrollingEnabled="false"
 android:layout_width="match_parent"
 android:layout_height="match_parent" />

2

Nếu bạn đang sử dụng RecyclerView ScrollListener bên trong NestedScrollView , trình nghe addOnScrollListener không hoạt động đúng nếu bạn sử dụng cả hai.

Sử dụng mã này.

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState); 
              ......
        }
    });

mã này hoạt động tốt RecyclerView ScrollListener bên trong NestedScrollView .

cảm ơn


1

Tôi đã phải thực hiện Điều phối viên với việc cuộn thanh công cụ và tôi chỉ mất cả ngày để loay hoay với việc này. Tôi đã làm cho nó hoạt động bằng cách loại bỏ NestedScrollView. Vì vậy, tôi chỉ sử dụng RelativeLayout ở thư mục gốc.

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

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_nearby"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</RelativeLayout>

1

không sử dụng recyclerView bên trong NestedScrollView. nó có thể gây ra vấn đề xếp tầng! Tôi đề nghị sử dụng ItemViewTypes trong RecyclerView để xử lý nhiều loại chế độ xem. chỉ cần thêm RecyclerView với match_parent chiều rộng và chiều cao. sau đó trong recyclerViewAd CHƯƠNG của bạn ghi đè getItemViewType và sử dụng vị trí để xử lý bố cục nào sẽ bị thổi phồng. sau đó, bạn có thể xử lý trình giữ khung nhìn của mình bằng cách sử dụng phương thức onBindViewHolder.


1
nestedScrollView.setNestedScrollingEnabled(true);

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            //...
        }
    });


<androidx.core.widget.NestedScrollView
    android:id="@+id/nested"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    android:layout_below="@id/appBarLayout_orders"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"> 

    <androidx.constraintlayout.widget.ConstraintLayout ...

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"/>

0

Tôi đã sử dụng phần mở rộng tuyệt vời này (được viết bằng kotlin nhưng cũng có thể được sử dụng bằng Java)

https://github.com/Widgetlabs/expedition-nestedscrollview

Về cơ bản, bạn nhận được NestedRecyclerViewbên trong bất kỳ gói nào cho phép sử dụng các tiện ích trong dự án của bạn, sau đó chỉ cần tạo recyclerview của bạn như

 <com.your_package.utils.NestedRecyclerView
      android:id="@+id/rv_test"
      android:layout_width="match_parent"
      android:layout_height="match_parent" />

Kiểm tra bài viết tuyệt vời này của Marc Knaup

https://medium.com/widgetlabs-engineering/scrollable-nestedscrollview-inside-recyclerview-ca65050d828a


0

Giải pháp cho việc không tải tất cả con xem tái chế cùng một lúc trong chế độ xem cuộn lồng nhau .

Trang phục:

  1. không tải tất cả con một lần, khi sử dụng chế độ xem cuộn lồng nhau.
  2. bạn có thể sử dụng recyclView.setHasFixedSize (true) để có hiệu suất tốt hơn
  3. ngăn dịch vụ web gửi tất cả dữ liệu cùng một lúc, phân trang hoạt động như mong đợi
  4. tốt cho số lượng lớn hơn các bộ dữ liệu.
  5. tốt cho các thiết bị bộ nhớ thấp
  6. có thể tiếp tục sử dụng cuộn cuộn lồng nhau
  7. rất hữu ích khi recyle của bạn xem mục phức tạp và đòi hỏi nhiều tài nguyên.

Sửa chữa :

trong xml của bạn thay vì sử dụng match_parent hoặc wrap_content để sử dụng recycleview chiều cao sửa chữa .


-5

RecyclerView với NestedScrollView

    <android.support.v7.widget.RecyclerView
    android:id="@+id/rv"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.