Personaly 나는 이것을 위해 RecyclerView를 하위 클래스로 만들고 싶지 않습니다. 왜냐하면 저에게는 GridLayoutManager의 책임이 스팬 수를 감지하는 것 같기 때문입니다. 따라서 RecyclerView 및 GridLayoutManager에 대한 일부 Android 소스 코드를 파고 난 후 작업을 수행하는 자체 클래스 확장 GridLayoutManager를 작성했습니다.
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에서 스팬 수를 설정하기로 선택한 이유를 실제로 기억하지 못합니다.이 클래스는 얼마 전에 작성했습니다. 그러나 요점은 뷰가 측정 된 후에 그렇게해야한다는 것입니다. 높이와 너비를 얻을 수 있습니다.
편집 1 : 코드의 오류를 수정하여 스팬 수를 잘못 설정했습니다. 솔루션 을보고하고 제안 해 주신 @Elyees Abouda 사용자 에게 감사드립니다 .
편집 2 : 일부 작은 리팩토링 및 수동 방향 변경 처리로 가장자리 케이스를 수정합니다. 보고하고 해결책을 제안 해 주신 @tatarize 사용자 에게 감사드립니다 .
LayoutManager
아이들을 배치하는 것이 아니라RecyclerView
's가 아닌 배치하는