如何在NestedScrollView中使用RecyclerView?

如何在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> 

用您的recyclerViewreplace,

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

这里,

 app:layout_behavior="@string/appbar_scrolling_view_behavior" 

将pipe理其余的事情。

还有一件事,不需要把你的recyclerView放到NestedScrollView中

UPDATE

自Android支持库23.2.0以来,LayoutManagers添加了方法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); 

旧的答案(不推荐)

你可以在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); } } 

之后,使用您的RecyclerView这个LayoutManager

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

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

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

这里setNestedScrollingEnabled(false)禁用RecyclerView滚动,所以它不会拦截NestedScrollView滚动事件。 并且setHasFixedSize(false)确定适配器内容的更改可以更改RecyclerView的大小

重要提示:这个解决scheme在某些情况下是小错误,并且在性能方面存在问题,所以如果您的RecyclerView有很多项目,我build议使用自定义的基于LinearLayout的列表视图的实现,为它创buildAdapter的模拟器,使其行为像ListViewRecyclerView

1)您需要使用支持库23.2.0(或)以上

2)和recyclerView的高度将是wrap_content。

3)recyclerView.setNestedScrollingEnabled(false)

但通过这样做,回收模式不起作用。 (即所有的视图都会一次加载,因为wrap_content需要完整的recyclerView的高度,所以它将一次绘制所有的回收站视图,没有视图将被回收)。 尽量不要使用这种模式util。 尝试使用viewType并添加需要滚动到recyclerView的所有其他视图

你可以使用android:fillViewport="true"来使NestedScrollView测量RecyclerViewRecyclerView将填充剩余的高度。 所以如果你想滚动NestScrollView ,你可以设置RecyclerViewminHeight

只需添加recyclerView.setNestedScrollingEnabled(false); 之前setAdapter本身为我工作。 我没有添加app:layout_behavior="@string/appbar_scrolling_view_behavior"任何地方也没有设置任何自定义布局pipe理器

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

这是为我工作

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

尝试使用这个库 – https://github.com/serso/android-linear-layout-manager

库的LayoutManager使RecyclerView包装其内容。 在这种情况下,RecyclerView将“与内部视图一样大”,所以它不会有滚动条,用户将使用NestedScrollView的滚动function。 因此,它不会像“可滚动滚动内容”那样含糊不清。

有一个简单的testing代码,你可以检查

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

我在一个NestedScrollView中使用RecyclerView ,它为我工作。 唯一需要记住的是NestedScrollView只有一个子视图。 所以在我的情况下,我使用了LienearLayout视图组,这是我的RecyclerView外加一些我需要的其他视图。

我遇到一个问题,把我的RecyclerView内NestedScrollView。 我意识到,滚动我的RecyclerView松弛的内容。

后来我意识到我的RecyclerView正在接收滚动事件,因此与NestedScrollView的滚动行为冲突。

所以要解决这个问题,我必须禁用我的RecyclerView的滚动function与此方法movieListNewRecyclerView.setNestedScrollingEnabled(false);

你可以在我的Instagram上看看我实际做了什么的短片。 这是我的instagram句柄ofelix03

点击这个图片看看我做了什么

如果您使用RecyclerView-23.2.1或更高版本。 以下解决scheme将工作得很好:

在你的布局中添加像这样的RecyclerView:

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

并在您的Java文件中:

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

这里layoutManager.setAutoMeasureEnabled(true); 会做的伎俩。

看看这个问题和这个开发人员的博客了解更多信息。

这里是我用来避免滚动问题的代码:

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

您不能在嵌套滚动视图中使用回收站视图。 它并不打算包含更多的可滚动视图,但是这是因为它是一个滚动布局本身的孩子,所以你需要嵌套的滚动视图。 我有同样的问题,但最终我将我的textview移动到recyclerview中的headerview,使recyclerview成为协调器布局的直接子节点,并删除嵌套的滚动视图。 那么我所有的问题都没有了。

我有NestedScrollView内的Viewpager和RecyclerView。 添加下面的行后

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

我解决了慢滚动和滚动滞后问题。

我不得不使用工具栏滚动来实现CoordinatorLayout,它只是花了我整整一天的时间。 我已经通过删除NestedScrollView工作。 所以我只是在根上使用RelativeLayout。

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

RecyclerView与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" />