public class FlowLayout extends ViewGroup {
public FlowLayout(Context context) {
super(context);
}
public FlowLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
//子View个数
int childCount = getChildCount();
//计算FlawLayout所占大小
//一行宽度
int lineWidth = 0;
//一行高度
int lineHeight = 0;
//总高度
int width = 0;
//总宽度
int height = 0;
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
measureChild(child, widthMeasureSpec, heightMeasureSpec);
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
int childWidth = child.getWidth() + lp.leftMargin + lp.rightMargin;
int childHeight = child.getHeight() + lp.topMargin + lp.bottomMargin;
//判断需不需要换行
if (lineWidth + childWidth > widthSize) {
//换行
//取最大总宽度
width = Math.max(width, lineWidth);
//总高度累加
height += lineHeight;
//初始化行宽高
lineHeight = childHeight;
lineWidth = childWidth;
} else {
//不换行
//取最大行高
lineHeight = Math.max(lineHeight, childHeight);
//行宽累加
lineWidth += childWidth;
}
//处理最后一行
if (i == childCount - 1) {
//总高度累加
height += lineHeight;
//取最大总宽度
width = Math.max(lineWidth, width);
}
}
//设置测量大小
setMeasuredDimension(widthMode == MeasureSpec.EXACTLY ? widthSize : width,
heightMode == MeasureSpec.EXACTLY ? heightSize : height);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childCount = getChildCount();
int lineHeight = 0;//行宽
int lineWidth = 0;//行高
int top = 0, left = 0;//当前top、left坐标
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
//判断是否换行
if (childWidth + lineWidth > getMeasuredWidth()) {
//换行
top += lineHeight;//高度累加
left = 0;//宽度置0
lineHeight = childHeight;//初始化行高
lineWidth = childWidth;//初始化行宽
} else {
//不换行
lineWidth += childWidth;//行宽累加
lineHeight = Math.max(lineHeight, childHeight);//计算最大行高
}
//计算ChildView的left、top、right、bottom
int lc = left + lp.leftMargin;
int tc = top + lp.topMargin;
int rc = lc + child.getMeasuredWidth();
int bc = tc + child.getMeasuredHeight();
child.layout(lc, tc, rc, bc);
//将left置为下一个子View起点
left += childWidth;
}
}
//覆写以下三个方法 以便获取MarginLayoutParams
@Override
protected LayoutParams generateDefaultLayoutParams() {
return new MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MarginLayoutParams(getContext(), attrs);
}
@Override
protected LayoutParams generateLayoutParams(LayoutParams p) {
return new MarginLayoutParams(p);
}
}
FlowLayout简易版
最新推荐文章于 2024-03-24 20:28:22 发布