Về cơ bản, tôi không thích phân lớp RecyclerView cho điều này, vì đối với tôi, có vẻ như GridLayoutManager có trách nhiệm phát hiện số lượng khoảng cách. Vì vậy, sau khi đào một số mã nguồn android cho RecyclerView và GridLayoutManager, tôi đã viết GridLayoutManager mở rộng lớp của riêng mình để thực hiện công việc:
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);
}
}
Tôi thực sự không nhớ lý do tại sao tôi chọn đặt số lượng khoảng cách trong onLayoutChildren, tôi đã viết lớp này một thời gian trước. Nhưng vấn đề là chúng ta cần phải làm như vậy sau khi lượt xem được đo lường. vì vậy chúng tôi có thể lấy chiều cao và chiều rộng của nó.
CHỈNH SỬA 1: Sửa lỗi trong mã do đặt sai số khoảng thời gian. Cảm ơn người dùng @Elyees Abouda đã báo cáo và đề xuất giải pháp .
CHỈNH SỬA 2: Một số cấu trúc lại nhỏ và sửa trường hợp cạnh với xử lý thay đổi hướng thủ công. Cảm ơn người dùng @tatarize đã báo cáo và đề xuất giải pháp .
LayoutManager
's công việc đẻ con ra ngoài và khôngRecyclerView
' s