AGGIORNAMENTO 1
Dalla libreria di supporto Android 23.2.0 sono stati aggiunti metodi setAutoMeasureEnabled(true)
per LayoutManager. Fa sì che RecyclerView racchiuda il suo contenuto e funzioni come un fascino.
http://android-developers.blogspot.ru/2016/02/android-support-library-232.html
Quindi aggiungi qualcosa di simile a questo:
LayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setAutoMeasureEnabled(true);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setNestedScrollingEnabled(false);
AGGIORNAMENTO 2
Poiché 27.1.0 setAutoMeasureEnabled
è obsoleto, è necessario fornire un'implementazione personalizzata di LayoutManager con metodo ignoratoisAutoMeasureEnabled()
Ma dopo molti casi di utilizzo RecyclerView consiglio vivamente di non usarlo in modalità wrapping , perché questo non è quello a cui è destinato. Prova a rielaborare l'intero layout utilizzando il normale RecyclerView singolo con diversi tipi di elementi. Oppure usa l'approccio con LinearLayout che ho descritto di seguito come ultima risorsa
Vecchia risposta (non consigliata)
Puoi usare RecyclerView
dentro NestedScrollView
. Prima di tutto dovresti implementare la tua personalizzazione LinearLayoutManager
, ti fa RecyclerView
avvolgere il suo contenuto. Per esempio:
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);
}
}
Dopodiché usalo LayoutManager
per il tuoRecyclerView
recyclerView.setLayoutManager(new WrappingLinearLayoutManager(getContext()));
Ma dovresti anche chiamare questi due metodi:
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(false);
Qui setNestedScrollingEnabled(false)
disabilita lo scorrimento per RecyclerView
, quindi non intercetta l'evento di scorrimento da NestedScrollView
. E setHasFixedSize(false)
determinare che le modifiche al contenuto dell'adattatore possono cambiare la dimensione diRecyclerView
Nota importante: in alcuni casi questa soluzione è un po 'buggy e presenta problemi di prestazioni, quindi se hai molti elementi nel tuo RecyclerView
consiglio di utilizzare l' LinearLayout
implementazione personalizzata della vista elenco, creare un analogo di Adapter per esso e renderlo comportarsi come ListView
oRecyclerView