在网上找到的 AutoLineFeedLayoutManager 自动换行布局管理器(靠左布局)上做了修改,以支持
换行后实现居中布局。
效果如下图:
(原创作品,转载请声明出处:https://blog.csdn.net/hegan2010/article/details/113102364)
代码如下:
import android.content.Context;
import android.util.AttributeSet;
import android.util.Size;
import android.view.View;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.LinkedHashMap;
import java.util.Map;
public class AutoLineFeedLayoutManager extends LinearLayoutManager {
public AutoLineFeedLayoutManager(Context context) {
super(context);
//setOrientation(RecyclerView.HORIZONTAL);
}
public AutoLineFeedLayoutManager(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
//setOrientation(RecyclerView.HORIZONTAL);
}
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new RecyclerView.LayoutParams(
RecyclerView.LayoutParams.WRAP_CONTENT, RecyclerView.LayoutParams.WRAP_CONTENT);
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
onAverageLayoutChildren(recycler, state);
}
public void onLeftLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
detachAndScrapAttachedViews(recycler);
int parentWidth = getWidth();
int curLineWidthSum = 0;
int curLineTop = 0;
int lastLineMaxHeight = 0;
for (int i = 0, count = getItemCount(); i < count; i++) {
View view = recycler.getViewForPosition(i);
addView(view);
measureChildWithMargins(view, 0, 0);
int width = getDecoratedMeasuredWidth(view);
int height = getDecoratedMeasuredHeight(view);
curLineWidthSum += width;
if (curLineWidthSum <= parentWidth) {
layoutDecorated(view,
curLineWidthSum - width, curLineTop, curLineWidthSum, curLineTop + height);
if (lastLineMaxHeight < height) {
lastLineMaxHeight = height;
}
} else {
curLineWidthSum = width;
if (lastLineMaxHeight == 0) {
lastLineMaxHeight = height;
}
curLineTop += lastLineMaxHeight;
layoutDecorated(view, 0, curLineTop, width, curLineTop + height);
lastLineMaxHeight = height;
}
}
}
private void onAverageLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
detachAndScrapAttachedViews(recycler);
int parentWidth = getWidth();
int curLineWidthSum = 0;
int curLineTop = 0;
int lastLineMaxHeight = 0;
Map<View, Size> lastLineMap = new LinkedHashMap<>();
for (int i = 0, count = getItemCount(); i < count; i++) {
View view = recycler.getViewForPosition(i);
addView(view);
measureChildWithMargins(view, 0, 0);
int width = getDecoratedMeasuredWidth(view);
int height = getDecoratedMeasuredHeight(view);
curLineWidthSum += width;
if (curLineWidthSum <= parentWidth) {
lastLineMap.put(view, new Size(width, height));
if (lastLineMaxHeight < height) {
lastLineMaxHeight = height;
}
} else {
int lastLineSize = lastLineMap.size();
if (lastLineSize > 0) {
int widthOffset = (parentWidth - curLineWidthSum + width) / (lastLineSize + 1);
int idxLeft = widthOffset;
for (Map.Entry<View, Size> entry : lastLineMap.entrySet()) {
View idxView = entry.getKey();
Size idxSize = entry.getValue();
int idxRight = idxLeft + idxSize.getWidth();
layoutDecorated(idxView,
idxLeft, curLineTop, idxRight, curLineTop + idxSize.getHeight());
idxLeft = idxRight + widthOffset;
}
lastLineMap.clear();
}
lastLineMap.put(view, new Size(width, height));
curLineWidthSum = width;
if (lastLineMaxHeight == 0) {
lastLineMaxHeight = height;
}
curLineTop += lastLineMaxHeight;
lastLineMaxHeight = height;
}
}
int lastLineSize = lastLineMap.size();
if (lastLineSize > 0) {
int widthOffset = (parentWidth - curLineWidthSum) / (lastLineSize + 1);
int idxLeft = widthOffset;
for (Map.Entry<View, Size> entry : lastLineMap.entrySet()) {
View idxView = entry.getKey();
Size idxSize = entry.getValue();
int idxRight = idxLeft + idxSize.getWidth();
layoutDecorated(idxView,
idxLeft, curLineTop, idxRight, curLineTop + idxSize.getHeight());
idxLeft = idxRight + widthOffset;
}
}
lastLineMap.clear();
}
}