/**
* 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);
}