一,FlowLayout
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 onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//1.测量所有孩子宽高
measureChildren(widthMeasureSpec, heightMeasureSpec);
//2.测量
int widthSize = MeasureSpec.getSize(widthMeasureSpec);//设置精确宽度
int widthMode = MeasureSpec.getMode(widthMeasureSpec);//设置精确模式
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
//3.声明属性
int width=0;//最终的宽
int height=0;//最终的高
int lineWidth=0;//行宽
int lineHeight=0;//行高
int totaiHeight=0;//总高度
int childWidth=0;//孩子的宽
int childHeight=0;//孩子的高
View childView; //加载的子布局
//4.遍历子布局
for (int i = 0; i <getChildCount() ; i++) {
//1.拿到每个孩子的下标
childView=getChildAt(i);
//2.测量孩子的宽高
childWidth= childView.getMeasuredWidth();
childHeight = childView.getMeasuredHeight();
//3.判断 孩子的宽大于精确宽度抛个异常
if(childWidth>widthSize){
throw new IllegalArgumentException("子布局的宽度不能大于屏幕精确宽度");
}
//5.判断 行宽+孩子的宽 如果大于精确宽度就换行 不大于就不换行
if(lineWidth+childWidth>widthSize){
//换行
width=widthSize;
totaiHeight+=lineHeight;
lineHeight=childHeight;
lineWidth=childWidth;
}else{
//不换行
lineWidth+=childWidth;
//当前行的高度
lineHeight=Math.max(lineHeight,childHeight);
//假如只有一行,那测量的宽度就是当前行宽,如果又换行那就去最大宽
width=Math.max(width,lineWidth);
}
//5. //当结束遍历的时候要加上最后一行的高度
if(i==getChildCount()-1){
totaiHeight+=lineHeight;
height=totaiHeight;
}
}
//6.设置模式
width=widthMode==MeasureSpec.EXACTLY? widthSize: width;
height=heightMode==MeasureSpec.EXACTLY ? heightSize:height;
//7.确定最终测量的宽高
setMeasuredDimension(width,height);
}
//布局
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int lineWidth=0;//行宽
int lineHeight=0;//行高
int totaiHeight=0;//总高度
int childWidth=0;//孩子的宽
int childHeight=0;//孩子的高
View childView; //加载的子布局
for (int i = 0; i < getChildCount(); i++) {
childView=getChildAt(i);
childWidth=childView.getMeasuredWidth();
childHeight=childView.getMeasuredHeight();
if(lineWidth+childWidth>getMeasuredWidth()){
//换行
totaiHeight+=lineHeight;
lineWidth=0;
layoutView(childView,lineWidth,totaiHeight,lineWidth+childWidth,totaiHeight+childHeight);
lineHeight=childHeight;
lineWidth=childWidth;
}else{
//不换行
layoutView(childView,lineWidth,totaiHeight,lineWidth+childWidth,totaiHeight+childHeight);
lineWidth+=childWidth;
lineHeight=Math.max(lineHeight,childHeight);
}
}
}
private void layoutView(View childView, int lineWidth, int totaiHeight, int i, int i1) {
childView.layout(lineWidth,totaiHeight,i,i1);
}
}
二,MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private static final String TAG = "MainActivity-===";
private EditText editText;
private Button button;
private FlowLayout flowLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = findViewById(R.id.edit_text);
button = findViewById(R.id.button);
flowLayout = findViewById(R.id.flow);
button.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.button:
//1.获取输入框的内容
String s = editText.getText().toString();
Log.d(TAG, "onClick: "+s);
//2.加载子布局的textview
TextView t=new TextView(MainActivity.this);
t.setText(s);//赋值
//t.setPadding(10,10,10,10);
t.setBackgroundColor(Color.RED);
flowLayout.addView(t);
break;
}
}
}