업데이트 1
Android 지원 라이브러리 23.2.0부터 setAutoMeasureEnabled(true)
LayoutManagers에 대한 메소드가 추가되었습니다 . 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를 사용하여 전체 레이아웃을 리팩토링하십시오. 또는 아래에 마지막 수단으로 설명한 LinearLayout을 사용하는 접근 방식
기존 답변 (권장하지 않음)
RecyclerView
내부에서 사용할 수 있습니다 NestedScrollView
. 우선 당신이 당신의 자신의 정의를 구현해야합니다 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
중요 사항 : 이 솔루션은 경우에 따라 거의 버그가 없으며 성능에 문제가 있으므로 많은 항목이있는 경우 목록 기반의 RecyclerView
사용자 정의 LinearLayout
기반 구현 을 사용하고 어댑터의 아날로그를 작성하여 작성하는 것이 좋습니다 처럼 행동 ListView
또는RecyclerView