package com.example.liushibuju;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
/** * Created by DELL on 2018/6/8. */ public class FlowLayout extends ViewGroup {
public FlowLayout(Context context) {
super(context);
}
public FlowLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onLayout(boolean b, int i, int i1, int i2, int i3) {
int lineWidth = 0;
int lineHeight = 0;
int totalHeight = 0;
View childView;
int childWidth = 0;
int childHeight = 0;
MarginLayoutParams layoutParams;
int leftMargin;
int rightMargin;
int topMargin;
int bottomMargin;
for (int j = 0; j < getChildCount(); j++) {
childView = getChildAt(j);
childWidth = childView.getMeasuredWidth();
childHeight = childView.getMeasuredHeight();
layoutParams = (MarginLayoutParams) childView.getLayoutParams();
leftMargin = layoutParams.leftMargin;
rightMargin = layoutParams.rightMargin;
topMargin = layoutParams.topMargin;
bottomMargin = layoutParams.bottomMargin;
if (lineWidth + childWidth + leftMargin + rightMargin > getMeasuredWidth() - getPaddingLeft() - getPaddingRight()) {
//换行 totalHeight += childHeight + topMargin + bottomMargin;
lineWidth = 0 + leftMargin;
layoutChildView(childView, lineWidth + leftMargin, totalHeight + topMargin, lineWidth + childWidth + leftMargin, totalHeight + childHeight + topMargin);
lineHeight = childHeight + topMargin + bottomMargin;
lineWidth = childWidth + leftMargin + rightMargin;
} else {
//不换行 layoutChildView(childView, lineWidth + leftMargin, totalHeight + topMargin, lineWidth + childWidth + leftMargin, totalHeight + childHeight + topMargin);
lineWidth += childWidth + leftMargin + rightMargin;
lineHeight = Math.max(lineHeight, childHeight + topMargin + bottomMargin);
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//测量所有孩子的宽高 measureChildren(widthMeasureSpec, heightMeasureSpec);
int widthsize = MeasureSpec.getSize(widthMeasureSpec);
int widthmode = MeasureSpec.getMode(widthMeasureSpec);
int heightsize = MeasureSpec.getSize(heightMeasureSpec);
int heightmode = MeasureSpec.getMode(heightMeasureSpec);
int width = 0;
int height = 0;
int lineWidth = 0;
int lineHeight = 0;
int totalHeight = 0;
int childWidth = 0;
int childHeight = 0;
View childView;
MarginLayoutParams layoutParams;
int leftMargin;
int rightMargin;
int topMargin;
int bottomMargin;
for (int i = 0; i < getChildCount(); i++) {
childView = getChildAt(i);
childWidth = childView.getMeasuredWidth();
childHeight = childView.getMeasuredHeight();
layoutParams = (MarginLayoutParams) childView.getLayoutParams();
leftMargin = layoutParams.leftMargin;
rightMargin = layoutParams.rightMargin;
topMargin = layoutParams.topMargin;
bottomMargin = layoutParams.bottomMargin;
if (childWidth + leftMargin + rightMargin > widthsize - getPaddingLeft() - getPaddingRight()) {
throw new IllegalArgumentException("子view的宽度不能大于父布局的宽度");
}
if (lineWidth + childWidth + leftMargin + rightMargin > widthsize - getPaddingLeft() - getPaddingRight()) {
//换行 width = widthsize;
totalHeight += lineHeight;
lineWidth = childWidth + leftMargin + rightMargin;
lineHeight = childHeight + topMargin + bottomMargin;
} else {
//不换行 lineWidth += childWidth + leftMargin + rightMargin;
//比较当前行的高度 lineHeight = Math.max(lineHeight, childHeight + topMargin + bottomMargin);
//比较当前宽度,如果没有换行那么宽度就是当前的行宽,否则就是最大宽 width = Math.max(width, lineWidth + getPaddingLeft() + getPaddingRight());
}
//当结束遍历的时候要加上最后一行的高 if (i == getChildCount() - 1) {
totalHeight += lineHeight;
height = totalHeight;
}
}
width = widthmode == MeasureSpec.EXACTLY ? widthsize : width;
height = heightmode == MeasureSpec.EXACTLY ? heightsize : height + getPaddingTop() + getPaddingBottom();
setMeasuredDimension(width, height);
}
public void layoutChildView(View child, int l, int t, int r, int b) {
//统一根据flowlayout设置的padding进行整体的平移 l += getPaddingLeft();
t += getPaddingTop();
r += getPaddingLeft();
b += getPaddingLeft();
child.layout(l, t, r, b);
}
@Override
protected LayoutParams generateDefaultLayoutParams() {
return new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
@Override
protected LayoutParams generateLayoutParams(LayoutParams p) {
return new MarginLayoutParams(p);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MarginLayoutParams(getContext(), attrs);
}
}