/**
* author : geyuecang
* date : 2019/4/23 15:15
* desc : desc
*/
public class FlexableLayout extends ViewGroup {
public FlexableLayout(Context context) {
this(context, null);
}
public FlexableLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FlexableLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//获取测量高度和测量模式
int measureWidth = MeasureSpec.getSize(widthMeasureSpec);
int measureHeight = MeasureSpec.getSize(heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int lineHeight = 0;// 记录行的高度
int lineWidth = 0; // 记录每行的宽度
int height = 0; // 记录总高度
int width = 0; // 记录总宽度
int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
measureChild(child, widthMeasureSpec, heightMeasureSpec);
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
if (lineWidth + childWidth > measureWidth) {
//当前行宽度加上当前child的宽度大于viewgroup的测量宽度,换行
width = Math.max(width, lineWidth);
height += lineHeight;
//记录新一行的宽高
lineWidth = childWidth;
lineHeight = childHeight;
} else {
//不用换行
lineWidth += childWidth;
lineHeight = Math.max(lineHeight, childHeight);
}
//最后一行不会超出width,所以不会走if里面的代码,所以要特殊处理
if (i == count - 1) {
height += lineHeight;
width = Math.max(width, lineWidth);
}
}
setMeasuredDimension(widthMode == MeasureSpec.EXACTLY ? measureWidth : width,
heightMode == MeasureSpec.EXACTLY ? measureHeight : height);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int lineHeight = 0;
int lineWidth = 0;
int top = 0;
int left = 0;
int count = getChildCount();
for (int i = 0; i < count; 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 (lineWidth + childWidth <= getMeasuredWidth()) {
//不换行
lineHeight = Math.max(lineHeight, childHeight);
lineWidth += childWidth;
} else {
//换行
top += lineHeight;
left = 0;
lineHeight = childHeight;
lineWidth = childWidth;
}
//计算child的l、t、r、b
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
left += childWidth;
}
}
}
@Override
protected LayoutParams generateLayoutParams(LayoutParams p)
{
return new MarginLayoutParams(p);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs)
{
return new MarginLayoutParams(getContext(), attrs);
}
@Override
protected LayoutParams generateDefaultLayoutParams()
{
return new MarginLayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
}
自定义流式布局FlexableLayot
最新推荐文章于 2022-10-19 11:41:16 发布