UPDATE 1
Seit Android Support Library 23.2.0 wurden Methoden setAutoMeasureEnabled(true)
für LayoutManager hinzugefügt . Dadurch kann RecyclerView den Inhalt verpacken und wirkt wie ein Zauber.
http://android-developers.blogspot.ru/2016/02/android-support-library-232.html
Fügen Sie einfach so etwas hinzu:
LayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setAutoMeasureEnabled(true);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setNestedScrollingEnabled(false);
UPDATE 2
Da 27.1.0 setAutoMeasureEnabled
veraltet ist, sollten Sie die benutzerdefinierte Implementierung von LayoutManager mit überschriebener Methode bereitstellenisAutoMeasureEnabled()
Nach vielen Fällen der Verwendung von RecyclerView empfehle ich jedoch dringend, es nicht im Wrapping-Modus zu verwenden , da dies nicht der Zweck ist. Versuchen Sie, Ihr gesamtes Layout mit normaler RecyclerView mit mehreren Elementtypen neu zu gestalten. Oder verwenden Sie den Ansatz mit LinearLayout, den ich unten als letzten Ausweg beschrieben habe
Alte Antwort (nicht empfohlen)
Sie können RecyclerView
innen verwenden NestedScrollView
. Zuallererst sollten Sie Ihre eigene Gewohnheit implementieren LinearLayoutManager
, damit Sie RecyclerView
den Inhalt einpacken können. Beispielsweise:
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);
}
}
Danach verwenden Sie dies LayoutManager
für IhreRecyclerView
recyclerView.setLayoutManager(new WrappingLinearLayoutManager(getContext()));
Sie sollten diese beiden Methoden aber auch aufrufen:
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(false);
Hier setNestedScrollingEnabled(false)
deaktivieren Scrollen für RecyclerView
, so dass es nicht abfangen Scrollen Ereignis aus NestedScrollView
. Und stellen Sie setHasFixedSize(false)
fest, dass Änderungen am Adapterinhalt die Größe des ändern könnenRecyclerView
Wichtiger Hinweis: Diese Lösung ist in einigen Fällen wenig fehlerhaft und weist Probleme mit der Leistung auf. Wenn Sie also viele Elemente in Ihrem Programm haben, würde RecyclerView
ich empfehlen, eine benutzerdefinierte LinearLayout
Implementierung der Listenansicht zu verwenden , ein Analogon des Adapters dafür zu erstellen und es zu erstellen benimm dich wie ListView
oderRecyclerView