MyRelativeLayout
public class MyRelativeLayout extends RelativeLayout { private EditText editText; private ImageView imageView; public MyRelativeLayout(Context context) { this(context,null); } public MyRelativeLayout(Context context, AttributeSet attrs) { this(context, attrs,0); } public MyRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(context); } private void initView(Context context) { //创建搜索框 RelativeLayout.LayoutParams pl_ed = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); pl_ed.addRule(RelativeLayout.CENTER_IN_PARENT);//居中 editText = new EditText(context); editText.setHint("请输入搜索内容"); editText.setTextSize(15); editText.setTextColor(Color.GRAY); addView(editText, pl_ed);//添加到视图 //创建搜索按钮 RelativeLayout.LayoutParams pl_img = new RelativeLayout.LayoutParams(50, 50); //pl_img.addRule(RelativeLayout.ALIGN_RIGHT);//居右 pl_img.leftMargin = 480; imageView = new ImageView(context); imageView.setImageResource(R.mipmap.rg); addView(imageView, pl_img);//添加到视图中 } //backImg public ImageView getBack() { return imageView; } //返回TextView供调用 public EditText getTitle() { return editText; } }
FlowLayout
public class FlowLayout extends ViewGroup { //所有子View,按行记录 private List<List<View>> mAllViews = new ArrayList<List<View>>(); //记录每一行的最大高度 private List<Integer> mLineHeight = new ArrayList<>(); private List<View> lineView; 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); mAllViews.clear(); mAllViews.clear(); //获取当前父容器给当前控件的大小和模式 int modeWidth = MeasureSpec.getMode(widthMeasureSpec); int sizeWidth = MeasureSpec.getSize(widthMeasureSpec); int modeHeight = MeasureSpec.getMode(heightMeasureSpec); int sizeHeight = MeasureSpec.getSize(heightMeasureSpec); //每一行的List lineView = new ArrayList<>(); // 如果是warp_content情况下,记录宽和高 int width = 0; int height = 0; //记录每一行的宽度,width不断取最大宽度 int lineWidth = 0; //每一行的高度,累加至height int lineHeight = 0; //当前控件的宽度 int childCount = getChildCount(); //遍历每个子元素 for (int i = 0; i < childCount; i++) { View childAt = getChildAt(i); //测量每一个childAt的宽和高 measureChild(childAt, widthMeasureSpec, heightMeasureSpec); // 得到childAt的lp MarginLayoutParams lp = (MarginLayoutParams) childAt.getLayoutParams(); //当前子控件实际占据的宽度 int childWidth = childAt.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; //当前子控件实际占据的高度 int childHeight = childAt.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; //如果加入当前child,则超出最大宽度,则的到目前最大宽度给width,类加height 然后开启新行 if (lineWidth + childWidth > sizeWidth) { width = Math.max(lineWidth, width);//取最大的 lineWidth = childWidth;//重新开启新行,开始记录 //记录View mAllViews.add(lineView); lineView = new ArrayList<>();//*************** lineView.add(childAt); //叠加当前高度 height += lineHeight; mLineHeight.add(lineHeight); //开启记录下一行的高度 lineHeight = childHeight; } else { //否则累加值lineWidth,lineHeight取最大高度 lineView.add(childAt); lineWidth += childWidth; lineHeight = Math.max(lineHeight, childHeight); } //如果是最后一个,则将当前记录的最大宽度和当前lineWidth做比较 if (i == childCount - 1) { width = Math.max(width, lineWidth); height += lineHeight; mAllViews.add(lineView); mLineHeight.add(lineHeight); } } //设置当前控件的宽高 setMeasuredDimension((modeWidth == MeasureSpec.EXACTLY) ? sizeWidth : width, (modeHeight == MeasureSpec.EXACTLY) ? sizeHeight : height); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { //存储每一行所有的childView List<View> lineViews = new ArrayList<View>(); int lineHeight = 0; int left = 0; int top = 0; //得到总行数 int lineNums = mAllViews.size(); for (int i = 0; i < lineNums; i++) { // 每一行的所有的views lineViews = mAllViews.get(i); // 当前行的最大高度 lineHeight = mLineHeight.get(i); // 遍历当前行所有的View for (int j = 0; j < lineViews.size(); j++) { View child = lineViews.get(j); if (child.getVisibility() == View.GONE) { continue; } MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); //计算childView的left,top,right,bottom 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 += child.getMeasuredWidth() + lp.rightMargin + lp.leftMargin; } left = 0; top += lineHeight; } } }
MainActivity
private FlowLayout fl; private MyRelativeLayout mrl; private Button clearData; private String[] datas = { "笔记本","空气净化器","安卓手机","超级大号圆珠笔","空气滤芯","超级大号钢笔" }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //创建数据 setData(); // 查找控件 mrl = (MyRelativeLayout) findViewById(R.id.mrl); clearData = (Button) findViewById(R.id.btn); //添加数据 ImageView back = mrl.getBack(); back.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //String mytitle = mrl.getTitle().toString(); 这是错误的 String mytitle = mrl.getTitle().getText().toString(); ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); lp.leftMargin = 15; lp.rightMargin = 15; lp.topMargin = 15; lp.bottomMargin = 15; TextView textView = new TextView(MainActivity.this); textView.setText(mytitle); textView.setTextColor(Color.BLACK); textView.setBackgroundColor(Color.GRAY); textView.setBackgroundResource(R.drawable.shape_text_border); fl.addView(textView,lp); } }); //清空数据 clearData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { fl.removeAllViews();//清空所有视图 fl.invalidate();//主线程刷新 } }); } private void setData() { fl = (FlowLayout) findViewById(R.id.fl); //布局 ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); lp.leftMargin = 15; lp.rightMargin = 15; lp.topMargin = 15; lp.bottomMargin = 15; for(int i = 0; i < datas.length; i ++){ TextView textView = new TextView(this); textView.setText(datas[i]); textView.setTextColor(Color.BLACK); textView.setBackgroundColor(Color.GRAY); textView.setBackgroundResource(R.drawable.shape_text_border); fl.addView(textView,lp); } }
shape_text_border.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <padding android:top="10dp" android:bottom="10dp" android:left="10dp" android:right="10dp"/> <corners android:radius="4dp"/> <stroke android:color="#ebebeb" android:width="1dp"/> </shape>