如何在NestedScrollView内使用RecyclerView ? 设置适配器后,RecyclerView内容不可见。

更新布局代码。

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

当前回答

如果你在NestedScrollView中使用RecyclerView ScrollListener, addOnScrollListener监听器不能正常工作。

使用这段代码。

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

这段代码工作良好的RecyclerView ScrollListener内的NestedScrollView。

谢谢

其他回答

下面是我用来避免滚动问题的代码:

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

您可以使用我的示例代码

    <?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <LinearLayout
        android:id="@+id/fl_all_brand"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:context=".view.fragment.AllBrandFragment">

        <androidx.core.widget.NestedScrollView
            android:id="@+id/parent"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            >

            <LinearLayout
                android:id="@+id/fl_all_brand1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"

                android:orientation="vertical">


                <!--<include layout="@layout/content_home" />-->

                <TextView
                    android:id="@+id/tv_title"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_marginStart="@dimen/_15sdp"
                    android:layout_marginTop="@dimen/_20sdp"
                    android:fontFamily="@font/lexend_semibold"
                    android:text="@string/DISPLAY_LIGHTS"
                    android:textColor="@color/gray_scale_placehold"
                    android:textSize="@dimen/_16ssp" />


                <LinearLayout
                    android:id="@+id/recyclerLayout"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/_280sdp">


                    <androidx.recyclerview.widget.RecyclerView
                        android:id="@+id/recyclerviewobj"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_marginStart="@dimen/_10sdp"
                        android:layout_marginTop="@dimen/_20sdp"
                        android:layout_marginEnd="@dimen/_10sdp"
                        android:orientation="horizontal"
                        android:nestedScrollingEnabled="false"
                        android:layout_marginBottom="@dimen/_20sdp"
                        app:layout_behavior="@string/appbar_scrolling_view_behavior"
                        app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"

                        />
                </LinearLayout>



                <TextView
                    android:id="@+id/notfound"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_marginStart="@dimen/_15sdp"
                    android:layout_marginTop="@dimen/_20sdp"
                    android:layout_marginBottom="@dimen/_20sdp"
                    android:fontFamily="@font/lexend_semibold"
                    android:text="@string/DISPLAY_LIGHTS"
                    android:gravity="center"
                    android:visibility="gone"
                    android:textColor="?attr/hintTextColors"
                    android:textSize="@dimen/_12ssp" />
                <TextView
                    android:id="@+id/recommendTitle"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_above="@+id/addDeviceLayout"
                    android:layout_below="@+id/recyclerviewobj"
                    android:layout_marginStart="@dimen/_16sdp"
                    android:layout_marginTop="@dimen/_7sdp"
                    android:fontFamily="@font/lexend_semibold"
                    android:text="@string/RECOMMENDATION"
                    android:textColor="@color/gray_scale_placehold"
                    android:textSize="@dimen/_16ssp" />

                <LinearLayout
                    android:id="@+id/addDeviceLayout"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_above="@+id/createRoomLayout"
                    android:layout_marginTop="@dimen/_14sdp"
                    android:background="?attr/buttonTextColor"
                    android:orientation="vertical"
                    tools:visibility="visible">

                    <ImageView
                        android:id="@+id/addBtn"
                        android:layout_width="@dimen/_28sdp"
                        android:layout_height="@dimen/_28sdp"
                        android:layout_marginStart="@dimen/_16sdp"
                        android:layout_marginTop="@dimen/_8sdp"
                        android:src="@drawable/ic_thermostates_icon"
                        app:tint="?attr/colorPrimaryDark" />

                    <TextView
                        android:id="@+id/addDevice"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="@dimen/_16sdp"
                        android:layout_marginTop="@dimen/_5sdp"
                        android:fontFamily="@font/lexend_bold"
                        android:text="@string/PROGRAM_DISPLAY_SENSOR_PLUGS"
                        android:textColor="?attr/colorPrimaryDark"
                        android:textSize="@dimen/_12ssp" />

                    <TextView
                        android:id="@+id/summry"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="@dimen/_16sdp"
                        android:layout_marginTop="@dimen/_8sdp"
                        android:layout_marginBottom="@dimen/_6sdp"
                        android:fontFamily="@font/lexend_medium"
                        android:text="@string/DISPLAY_SENSOR_SUB_TITLE"
                        android:textColor="?attr/secondaryTextColor"
                        android:textSize="@dimen/_9ssp" />

                    <RelativeLayout
                        android:id="@+id/container3"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="@dimen/_6sdp"
                        android:layout_marginTop="@dimen/_6sdp"
                        android:layout_marginBottom="@dimen/_10sdp">

                        <TextView
                            android:id="@+id/get_started"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_centerVertical="true"
                            android:layout_marginStart="@dimen/_10sdp"
                            android:fontFamily="@font/lexend_semibold"
                            android:text="@string/RECOMMENDED_GROUP"
                            android:textAllCaps="true"
                            android:textSize="@dimen/_9ssp" />

                        <ImageView
                            android:id="@+id/forward_arrow"
                            android:layout_width="@dimen/_16sdp"
                            android:layout_height="@dimen/_16sdp"
                            android:layout_alignParentEnd="true"
                            android:layout_marginRight="@dimen/_20sdp"
                            android:src="@drawable/ic_forward_arrow"
                            app:tint="?attr/colorPrimary" />

                    </RelativeLayout>
                </LinearLayout>

                <LinearLayout
                    android:id="@+id/createRoomLayout"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_alignParentBottom="true"
                    android:layout_marginTop="@dimen/_9sdp"
                    android:layout_marginBottom="@dimen/_20sdp"
                    android:background="?attr/buttonTextColor"
                    android:orientation="vertical"
                    tools:visibility="visible">

                    <ImageView
                        android:id="@+id/addBtnRoom"
                        android:layout_width="@dimen/_28sdp"
                        android:layout_height="@dimen/_28sdp"
                        android:layout_marginStart="@dimen/_16sdp"
                        android:layout_marginTop="@dimen/_8sdp"
                        android:src="@drawable/rgb_light_new"
                        app:tint="?attr/colorPrimaryDark" />

                    <TextView
                        android:id="@+id/addRooms"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="@dimen/_16sdp"
                        android:layout_marginTop="@dimen/_5sdp"
                        android:fontFamily="@font/lexend_bold"
                        android:text="@string/DISPLAY_RGBW"
                        android:textColor="?attr/colorPrimaryDark"
                        android:textSize="@dimen/_12ssp" />

                    <TextView
                        android:id="@+id/summry1"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="@dimen/_16sdp"
                        android:layout_marginTop="@dimen/_8sdp"
                        android:layout_marginBottom="@dimen/_6sdp"
                        android:fontFamily="@font/lexend_medium"
                        android:text="@string/PROGRAM_DISPLAY_RGB_MSG"
                        android:textColor="?attr/secondaryTextColor"
                        android:textSize="@dimen/_9ssp" />

                    <RelativeLayout
                        android:id="@+id/container99"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="@dimen/_6sdp"
                        android:layout_marginTop="@dimen/_6sdp"
                        android:layout_marginBottom="@dimen/_10sdp">

                        <TextView
                            android:id="@+id/get_started_1"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_centerVertical="true"
                            android:layout_marginStart="@dimen/_10sdp"
                            android:fontFamily="@font/lexend_semibold"
                            android:text="@string/RECOMMENDED_GROUP"
                            android:textAllCaps="true"
                            android:textSize="@dimen/_9ssp" />

                        <ImageView
                            android:id="@+id/forward_arrow1"
                            android:layout_width="@dimen/_16sdp"
                            android:layout_height="@dimen/_16sdp"
                            android:layout_alignParentEnd="true"
                            android:layout_marginRight="@dimen/_20sdp"
                            android:src="@drawable/ic_forward_arrow"
                            app:tint="?attr/colorPrimary" />

                    </RelativeLayout>
                </LinearLayout>




            </LinearLayout>

        </androidx.core.widget.NestedScrollView>
    </LinearLayout>

</layout>

这里使用recyclerview的属性

app:layout_behavior="@string/appbar_scrolling_view_behavior"

并像这样关闭recyclerview嵌套滚动

android:nestedScrollingEnabled="false"

更新1

自Android支持库23.2.0以来,为布局管理器添加了setAutoMeasureEnabled(true)方法。它使RecyclerView包装它的内容和工作就像一个魅力。 http://android-developers.blogspot.ru/2016/02/android-support-library-232.html

所以只需添加如下内容:

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

更新2

因为27.1.0的setAutoMeasureEnabled已弃用,所以你应该提供LayoutManager的自定义实现,覆盖方法isAutoMeasureEnabled()

但是经过多次使用RecyclerView后,我强烈建议不要在包装模式下使用它,因为这不是它的目的。尝试使用普通的单个RecyclerView与几个项目类型重构整个布局。或者使用线性布局的方法,我在下面描述作为最后的手段

旧答案(不推荐)

你可以在NestedScrollView中使用RecyclerView。 首先,你应该实现你自己的自定义LinearLayoutManager,它使你的RecyclerView包装它的内容。 例如:

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);
    }
}

之后,使用这个LayoutManager为您的RecyclerView

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

但你也应该调用这两个方法:

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

这里setNestedScrollingEnabled(false)禁用了RecyclerView的滚动,因此它不会从NestedScrollView中拦截滚动事件。setHasFixedSize(false)确定适配器内容的变化可以改变RecyclerView的大小

重要提示:这个解决方案是小bug在某些情况下,有问题与性能,所以如果你有很多项目在你的RecyclerView,我建议使用自定义线性布局的实现列表视图,为它创建类似的适配器,使其行为像ListView或RecyclerView

如果你想在NestedScrollView中使用RecyclerView,这是一个简单的技巧,只需设置:

RecyclerView

recyclerView.setHasFixedSize (false) (java / kt) android: nestedScrollingEnabled = " false " android: layout_height = " wrap_content " android: overScrollMode =“从不”

嵌套滚动视图

android:fillViewport=“true”

这是我的工作,你可以使用许多RecyclerView在NestedScrollView与此。

保持recyclerview的回收特性并避免recyclerview加载所有数据的一个解决方案是在recyclerview本身设置一个固定的高度。通过这样做,recyclerview只能加载它的高度所能显示给用户的东西,这样当你滚动到底部/顶部时,循环它的元素。