ส่วนตัวฉันไม่ชอบคลาสย่อย RecyclerView สำหรับสิ่งนี้เพราะสำหรับฉันดูเหมือนว่ามีความรับผิดชอบของ GridLayoutManager ในการตรวจจับจำนวนช่วง ดังนั้นหลังจากที่ซอร์สโค้ด Android บางตัวขุดสำหรับ RecyclerView และ GridLayoutManager ฉันจึงเขียน 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