public class Flowlayout extends ViewGroup {
private List<View> allChild = new ArrayList<>();
public Flowlayout(Context context) {
this(context, null);
}
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 onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 测量方法
// 1. 获取测量模式和大小
// 2. 判断是否是精确测量模式,如果是精确测量模式直接可以使用,如果是非精确测量,动态测量。
// 3. 如何动态测量
// 4. 获取自孩子数量,拿出自孩子的宽度 相加 判断是否超过容器宽度,超过了增加容器高度,把所有的自孩子遍历完成就可以确定容器的宽高
// 5. 调用setMeasuredDimension 让宽高生效。
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
// 定义两个变量,保存测量后的宽度和高度
int wMeasure = 0;
int hMeasure = 0;
// 判断测试模式,计算宽度和高度
if (widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.EXACTLY) {
wMeasure = widthSize;
hMeasure = heightSize;
} else {
// 非精确测量
wMeasure = widthSize;
// 动态计算高度
int childCount = getChildCount();
int currentLineWidth = 0; // 当前行已经使用了多宽
int row = 1;
int childWidth;
int childHeight;
allChild.clear();
for (int i = 0; i < childCount; i++) {
// 获取一个child
View childAt = getChildAt(i);
allChild.add(childAt);
childAt.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
childWidth = childAt.getMeasuredWidth();
childHeight = childAt.getMeasuredHeight();
currentLineWidth += childWidth;
if (currentLineWidth > widthSize) {
// 执行折行
currentLineWidth = childWidth;
row++;
}
hMeasure = row * childHeight;
}
//将集合顺序调转
Collections.reverse(allChild);
}
// 调用setMeasuredDimension 让测量的宽度和高度生效
setMeasuredDimension(wMeasure, hMeasure);
//若是感到以上方法比较多,难懂,可以直接写这一行代码
measureChildren(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// 控制子控件的摆放
// 先获取容器的宽度
int width = r - l;
int x = 0;
int y = 0;
int row = 1;
int childCount = allChild.size();
for (int i = 0; i < childCount; i++) {
View view = allChild.get(i);
int childWidth = view.getMeasuredWidth();
int childHeight = view.getMeasuredHeight();
x += childWidth;
if (x > width) {
x = childWidth;
row++;
}
y = row * childHeight;
view.layout(x - childWidth, y - childHeight, x, y);
}
}
}
//当点击搜索按钮时,我们获取搜索框中的内容,导入子控件的视图
//把视图加入 自定义的流失布局
btnSou.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String name = edName.getText().toString();
TextView textView = (TextView) View.inflate(FlowActivity.this,R.layout.tag,null);
textView.setText(name);
//点击事件,通过 子布局 添加
flowLayout.addView(textView);
}
});
//子控件布局