package com.example.jd.view; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import java.util.ArrayList; import java.util.List; /** * Created by nyj on 2018/5/17. */ public class MyView extends ViewGroup { //每行的高度 private List<Integer> mLineHeight = new ArrayList<>(); //储存所有的子view private List<List<View>> mAllChildViews = new ArrayList<>(); public MyView(Context context) { this(context, null); } public MyView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } //测量 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //测量宽和高 int sizeWidth = MeasureSpec.getSize(widthMeasureSpec); int sizeHeight = MeasureSpec.getSize(heightMeasureSpec); int modeWidth = MeasureSpec.getMode(widthMeasureSpec); int modeHeight = MeasureSpec.getMode(heightMeasureSpec); //如果宽高为wrap_content的情况 int width = 0; int height = 0; //记录每一行的宽高 int lineWidth = 0; int lineHeight = 0; //获取一个view的个数 int childCount = getChildCount(); //遍历循环每一个view的数值 for (int i = 0; i < childCount; i++) { View childAt = getChildAt(i); //测量view的宽高 measureChild(childAt, widthMeasureSpec, heightMeasureSpec); //得到LayoutParams MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams(); //子view占据的宽度 int childWidth = childAt.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; //子view的高度 int childHeight = childAt.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; //换行 if (lineWidth + childWidth > sizeWidth) { //对比得到最大的宽度 width = Math.max(width, lineWidth); //重置lineWidth lineWidth = childWidth; //记录行高 height += lineHeight; lineHeight = childHeight; } else { //叠加行宽 lineWidth += childWidth; //得到最大行高 lineHeight = Math.max(lineHeight, childHeight); } //处理最后一个子view if (i == childCount - 1) { width = Math.max(width, lineWidth); height += lineHeight; } } //wrap_content setMeasuredDimension(modeWidth == MeasureSpec.EXACTLY ? sizeWidth : width, modeHeight == MeasureSpec.EXACTLY ? sizeHeight : height); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } //布局 @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { mAllChildViews.clear(); mLineHeight.clear(); //获得当前ViewGroup的宽度 int width = getWidth(); int lineWidth = 0; int lineHeight = 0; // 记录当前行的View List<View> lineViews = new ArrayList<View>(); int childCount = getChildCount(); for (int f = 0; f < childCount; f++) { View child = getChildAt(f); MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); int childWidth = child.getMeasuredWidth(); int childHeight = child.getMeasuredHeight(); //如果需要换行 if (childWidth + lineWidth + lp.leftMargin + lp.rightMargin > width) { //记录LineHeight mLineHeight.add(lineHeight); //记录当前的Views mAllChildViews.add(lineViews); //重置行高 lineWidth = 0; lineHeight = childHeight + lp.topMargin + lp.bottomMargin; //重置view的集合 lineViews = new ArrayList(); } lineWidth += childWidth + lp.leftMargin + lp.rightMargin; lineHeight = Math.max(lineHeight, childHeight + lp.topMargin + lp.bottomMargin); lineViews.add(child); } //处理最后一行 mLineHeight.add(lineHeight); mAllChildViews.add(lineViews); //设置子View的位置 int left = 20; int top = 100; //获取行数 int lineCount = mAllChildViews.size(); for (int d = 0; d < lineCount; d++) { //当前行的Views和高度 lineViews = mAllChildViews.get(d); lineHeight = mLineHeight.get(d); for (int j = 0; j < lineViews.size(); j++) { View child = lineViews.get(j); //判断是否显示 if (child.getVisibility() == View.GONE) { continue; } MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); int cLeft = left + lp.leftMargin; int cTop = top + lp.topMargin; int cRight = cLeft + child.getMeasuredWidth(); int cBottom = cTop + child.getMeasuredHeight(); //进行子View进行布局 child.layout(cLeft, cTop, cRight, cBottom); left += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; } left = 20; top += lineHeight; } } /** * 与当前ViewGroup对应的LayoutParams */ @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { // TODO Auto-generated method stub return new MarginLayoutParams(getContext(), attrs); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.liushilayout.MainActivity"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/sou_sou" android:layout_width="260dp" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:background="@drawable/shape_sou" android:hint="搜索...." /> <TextView android:id="@+id/sou_msg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toEndOf="@+id/sou_sou" android:layout_toRightOf="@+id/sou_sou" android:text="搜索" /> </RelativeLayout> <com.example.liushilayout.MyView android:id="@+id/sou_view" android:layout_width="wrap_content" android:layout_height="0dp" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_weight="9"></com.example.liushilayout.MyView> <android.support.v7.widget.RecyclerView android:id="@+id/sou_rcy" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="2"></android.support.v7.widget.RecyclerView> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center"> <Button android:id="@+id/sou_clear" android:layout_width="200dp" android:layout_height="50dp" android:background="@drawable/selector" android:text="清除历史记录" /> </LinearLayout> </LinearLayout>
<?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>
package com.example.liushilayout; import android.graphics.Color; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private String[] datas = {"笔记本", "空气净化器", "安卓手机", "超级大号圆珠笔", "空气滤芯", "超级大号钢笔"}; private TextView sou_msg; private EditText sou_sou; private MyView sou_view; private Button sou_clear; private RecyclerView sou_rcy; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); } private void initData() { ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); lp.leftMargin = 5; lp.rightMargin = 5; lp.topMargin = 5; lp.bottomMargin = 5; for (int i = 0; i < datas.length; i++) { TextView textView = new TextView(MainActivity.this); textView.setText(datas[i]); textView.setTextColor(Color.BLUE); textView.setTextSize(18); textView.setBackgroundResource(R.drawable.liushi); sou_view.addView(textView, lp); } } private void initView() { sou_msg = findViewById(R.id.sou_msg); sou_sou = findViewById(R.id.sou_sou); sou_view = findViewById(R.id.sou_view); sou_clear = findViewById(R.id.sou_clear); sou_rcy = findViewById(R.id.sou_rcy); //设置布局管理器 LinearLayoutManager linearLayoutManager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false); sou_rcy.setLayoutManager(linearLayoutManager); //监听 sou_msg.setOnClickListener(this); sou_view.setOnClickListener(this); sou_clear.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.sou_msg://点击搜索框 String s = sou_sou.getText().toString(); if (!s.equals("")) { ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); lp.leftMargin = 5; lp.rightMargin = 5; lp.topMargin = 5; lp.bottomMargin = 5; TextView textView = new TextView(MainActivity.this); textView.setText(s); textView.setTextSize(18); textView.setTextColor(Color.BLUE); textView.setBackgroundResource(R.drawable.liushi); sou_view.addView(textView, lp); } else { Toast.makeText(MainActivity.this, "请输入要搜索的内容", Toast.LENGTH_LONG).show(); } break; case R.id.sou_clear://清除 sou_view.removeAllViews(); sou_view.invalidate(); break; } } }
<?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>
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <!-- 填充的颜色 shape_sou--> <solid android:color="#fff" /> <!-- 设置边框宽度 --> <stroke android:width="1dp" android:color="#999999"/> <!-- 四个角的弧度 --> <corners android:bottomLeftRadius="15dp" android:bottomRightRadius="15dp" android:topLeftRadius="15dp" android:topRightRadius="15dp" /> <!-- padding:TextView里面的文字与TextView边界的间隔 --> <padding android:bottom="4dp" android:left="2dp" android:right="2dp" android:top="5dp" /> <!-- <size android:width="100dp" android:height="45dp"/> --> </shape>