Kişisel olarak RecyclerView'ı bunun için alt sınıflara ayırmayı sevmiyorum, çünkü benim için GridLayoutManager'ın aralık sayısını tespit etme sorumluluğu var gibi görünüyor. RecyclerView ve GridLayoutManager için bazı android kaynak kodu kazımından sonra, işi yapan kendi sınıf genişletilmiş GridLayoutManager yazdım:
public class GridAutofitLayoutManager extends GridLayoutManager
{
private int columnWidth;
private boolean isColumnWidthChanged = true;
private int lastWidth;
private int lastHeight;
public GridAutofitLayoutManager(@NonNull final Context context, final int columnWidth) {
/* Initially set spanCount to 1, will be changed automatically later. */
super(context, 1);
setColumnWidth(checkedColumnWidth(context, columnWidth));
}
public GridAutofitLayoutManager(
@NonNull final Context context,
final int columnWidth,
final int orientation,
final boolean reverseLayout) {
/* Initially set spanCount to 1, will be changed automatically later. */
super(context, 1, orientation, reverseLayout);
setColumnWidth(checkedColumnWidth(context, columnWidth));
}
private int checkedColumnWidth(@NonNull final Context context, final int columnWidth) {
if (columnWidth <= 0) {
/* Set default columnWidth value (48dp here). It is better to move this constant
to static constant on top, but we need context to convert it to dp, so can't really
do so. */
columnWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 48,
context.getResources().getDisplayMetrics());
}
return columnWidth;
}
public void setColumnWidth(final int newColumnWidth) {
if (newColumnWidth > 0 && newColumnWidth != columnWidth) {
columnWidth = newColumnWidth;
isColumnWidthChanged = true;
}
}
@Override
public void onLayoutChildren(@NonNull final RecyclerView.Recycler recycler, @NonNull final RecyclerView.State state) {
final int width = getWidth();
final int height = getHeight();
if (columnWidth > 0 && width > 0 && height > 0 && (isColumnWidthChanged || lastWidth != width || lastHeight != height)) {
final int totalSpace;
if (getOrientation() == VERTICAL) {
totalSpace = width - getPaddingRight() - getPaddingLeft();
} else {
totalSpace = height - getPaddingTop() - getPaddingBottom();
}
final int spanCount = Math.max(1, totalSpace / columnWidth);
setSpanCount(spanCount);
isColumnWidthChanged = false;
}
lastWidth = width;
lastHeight = height;
super.onLayoutChildren(recycler, state);
}
}
OnLayoutChildren'da neden yayılma sayısını ayarlamayı seçtiğimi gerçekten hatırlamıyorum, bu dersi bir süre önce yazmıştım. Ama mesele şu ki, görüş ölçüldükten sonra bunu yapmamız gerekiyor. böylece yüksekliğini ve genişliğini alabiliriz.
DÜZENLEME 1: Aralık sayısının yanlış ayarlanmasına neden olan koddaki hatayı düzeltin. @Elyees Abouda kullanıcısına rapor bildirdiği ve çözüm önerdiği için teşekkürler .
DÜZENLEME 2: Bazı küçük yeniden düzenleme ve manuel yönlendirme değişiklikleri işleme ile kenar durumu düzeltme. Teşekkür kullanıcı @tatarize raporlama ve öneren bir çözüm .
LayoutManager
Dışarısı çocukları bırakmaya iş değilRecyclerView
'ın