如何在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>
发布于 2015-09-23 17:00:15
将您的recyclerView替换为,
<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"
将会管理剩下的事情。
还有一件事,不需要把你的recyclerView放在NestedScrollView里面
发布于 2015-09-23 17:42:42
更新1
从安卓支持库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);
更新2
由于27.1.0 setAutoMeasureEnabled
已被弃用,因此您应该提供具有覆盖方法isAutoMeasureEnabled()
的LayoutManager的自定义实现
但在多次使用RecyclerView之后,我强烈建议不要在包装模式下使用它,因为这不是它的目的。尝试使用具有多个项目类型的普通单个RecyclerView来重构整个布局。或者使用我在下面描述为最后手段的LinearLayout方法
旧答案(不推荐)
您可以在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
的大小
重要提示:此解决方案在某些情况下存在小错误,并存在性能问题,因此,如果您的RecyclerView
中有很多项,我建议您使用列表视图的自定义LinearLayout
-based实现,为其创建类似适配器,并使其行为类似于ListView
或RecyclerView
发布于 2016-05-02 15:56:55
上的支持库23.2.0 (或)
高度为wrap_content
.的
RecyclerView
recyclerView.setNestedScrollingEnabled(false)
但是这样做,回收器模式就不起作用了,。(也就是说,所有的视图将被一次加载,因为wrap_content
需要完整的RecyclerView
的高度,所以它将一次绘制所有子Views
。不会回收任何视图)。除非确实需要,否则请尽量不要使用此模式。尝试使用viewType
并添加需要滚动到RecyclerView
的所有其他视图,而不是在Scrollview
中使用RecyclerView
。这对性能的影响将非常大。
为了简单起见,“它只是充当所有子视图的LinearLayout
”。
https://stackoverflow.com/questions/31000081
复制相似问题