自定义布局每行都全部显示(取列最大)
此自定义布局是为了实现设置一个列值,通过获取每一列的最大子view宽度让view全部展示效果
先看效果
使用
ColumnVerticalLayout mGridLayout = new ColumnVerticalLayout(context);
mGridLayout.setAverage(true);
mGridLayout.setColumn(3);
RelativeLayout.LayoutParams rlpGridLayout = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
rlpGridLayout.addRule(RelativeLayout.BELOW, mAvatar.getId());
addView(mGridLayout, rlpGridLayout);
自定义ViewGroup
public static class ColumnVerticalLayout extends ViewGroup {
private boolean IsAverage;//平均padding以及item之间的padding
private boolean IsAverageItemPadding;//平均item之间的padding
private int column;
public ColumnVerticalLayout(Context context) {
super(context);
}
public ColumnVerticalLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ColumnVerticalLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = getPaddingTop() + getPaddingBottom();
int rowHeight = 0;
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
childView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), heightMeasureSpec);
rowHeight = Math.max(rowHeight, childView.getMeasuredHeight());
if ((i + 1) % column == 0 || i == childCount - 1) {
height += rowHeight;
rowHeight = 0;
}
}
setMeasuredDimension(widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, MeasureSpec.getMode(heightMeasureSpec)));
}
@Override
protected void onLayout(boolean flag, int l, int t, int r, int b) {
int paddingLeft = getPaddingLeft();
int childCount = getChildCount();
int row = childCount / column;
int[] columnChildsWidth = new int[column];//存每一列的最大宽度
int itemPadding = 0;
int columnChildsWidthSum = 0;
for (int i = 0; i < childCount; i++) {
int curColumn = i % column;
for (int j = 0; j < row && i < column; j++) {//遍历每一列寻找每列childView的最大宽度
View childView = getChildAt(j * column + curColumn);
columnChildsWidth[curColumn] = Math.max(columnChildsWidth[curColumn], childView.getMeasuredWidth());
if (IsAverage) {
if (j == row - 1) {
columnChildsWidthSum += columnChildsWidth[curColumn];
}
} else if (IsAverageItemPadding) {
if (i == column - 1) {
itemPadding = getMeasuredWidth() - paddingLeft;
for (int k = 0; k < column; k++) {
itemPadding = itemPadding - columnChildsWidth[k];
}
itemPadding = (itemPadding - getPaddingRight()) / (column - 1);
}
}
}
}
if (IsAverage) {
itemPadding = (getMeasuredWidth() - columnChildsWidthSum) / (column + 1);
}
int curChildViewLeft = IsAverage ? itemPadding : paddingLeft;
int currentHeight = 0;
int top = getPaddingTop();
for (int i = 0; i < childCount; i++) {
int curColumn = i % column;
View childView = getChildAt(i);
childView.layout(curChildViewLeft, top, curChildViewLeft + columnChildsWidth[curColumn], top + childView.getMeasuredHeight());
curChildViewLeft += columnChildsWidth[curColumn] + itemPadding;
currentHeight = Math.max(currentHeight, childView.getMeasuredHeight());
if ((i + 1) % column == 0) {
top += currentHeight;
curChildViewLeft = IsAverage ? itemPadding : paddingLeft;
}
}
}
public void setColumn(int column) {
this.column = column;
}
public void setAverage(boolean average) {
IsAverage = average;
}
public void setAverageItemPadding(boolean averageItemPadding) {
IsAverageItemPadding = averageItemPadding;
}
}