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 on 2018/5/29. */ public class FlowLayout extends ViewGroup { // 存储当前ViewGroup的所有View,在Actvity中直接用addView(View view)添加; private List<List<View>> mAllViews = new ArrayList<List<View>>(); // 把每一行数据的高度存储到List private List<Integer> mHeightList = new ArrayList<Integer>(); 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 onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) { mAllViews.clear(); mHeightList.clear(); int width = getWidth(); int overWidth = 0;//每一个view所占据的总宽度margin,padding int overHeight = 0;//每一个view所占据的总高度 List<View> lineViews = new ArrayList<View>(); int viewCount = getChildCount();//把有View的总数量 for (int i = 0; i < viewCount; i++) { View child = getChildAt(i);//每一个子View MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); int childViewWdth = child.getMeasuredWidth(); int childViewHeight = child.getMeasuredHeight(); //当前View超过一行时,换行处理 if (childViewWdth + overWidth + lp.leftMargin + lp.rightMargin > width-getPaddingLeft()-getPaddingRight()) {// 换行判断 mHeightList.add(overHeight); mAllViews.add(lineViews); // 重置行宽和行高 overWidth = 0; overHeight = childViewHeight + lp.topMargin + lp.bottomMargin; // 重置我们的View集合 lineViews = new ArrayList<View>(); } overWidth += childViewWdth + lp.leftMargin + lp.rightMargin; overHeight = Math.max(overHeight, childViewHeight + lp.topMargin + lp.bottomMargin); lineViews.add(child); } // 处理最后一行 mHeightList.add(overHeight); mAllViews.add(lineViews); // 设置每一个子View的位置 int childLeft = getPaddingLeft(); int childTop = getPaddingTop(); // 当前行数 int linesNum = mAllViews.size(); for (int i = 0; i < linesNum; i++) { // 当前行的所有view lineViews = mAllViews.get(i); overHeight = mHeightList.get(i); for (int j = 0; j < lineViews.size(); j++) { View child = lineViews.get(j); // 判断当前View的状态 if (child.getVisibility() == View.GONE) { continue; } MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); int lc = childLeft + lp.leftMargin; int tc = childTop + lp.topMargin; int rc = lc + child.getMeasuredWidth(); int bc = tc + child.getMeasuredHeight(); child.layout(lc, tc, rc, bc);// 为子View进行布局 childLeft += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; } childLeft = getPaddingLeft(); childTop += overHeight; } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int sizeWidth = MeasureSpec.getSize(widthMeasureSpec); int modeWidth = MeasureSpec.getMode(widthMeasureSpec); int sizeHeight = MeasureSpec.getSize(heightMeasureSpec); int modeHeight = MeasureSpec.getMode(heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec); // wrap_content模式下的宽度和高度 int width = 0; int height = 0; // 记录每一行的宽度和高度 int lineWidth = 0; int lineHeight = 0; // 获取内容的View元素个数 int cCount = getChildCount(); for (int i = 0; i < cCount; i++) { View child = getChildAt(i); // 测量子View的宽度和高度 measureChild(child, widthMeasureSpec, heightMeasureSpec); // 得到LayoutParams MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); // 子View占据的宽度 int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; // 子View占据的高度 int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; // 换行处理 if (lineWidth + childWidth > sizeWidth - getPaddingLeft() - getPaddingRight()) { // 对比得到最大宽度 width = Math.max(width, lineWidth); // 重置 lineWidth = childWidth; // 记录行高 height += lineHeight; lineHeight = childHeight; } else { lineWidth += childWidth; // 获取当前行最大的高度 lineHeight = Math.max(lineHeight, childHeight); } if (i == cCount - 1) {// 如果是最后一个控件 width = Math.max(lineWidth, width); height += lineHeight; } } setMeasuredDimension( modeWidth == MeasureSpec.EXACTLY ? sizeWidth : width + getPaddingLeft() + getPaddingRight(), modeHeight == MeasureSpec.EXACTLY ? sizeHeight : height + getPaddingTop() + getPaddingBottom()); } /** * 与当前ViewGroup对应的Layoutparmas */ @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:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" android:orientation="vertical" tools:context="com.111.mysimulation.layou.MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/edit" android:layout_weight="2"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="搜" android:layout_weight="8" android:id="@+id/find"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="清" android:layout_weight="8" android:id="@+id/del"/> </LinearLayout> <com.bawei.mysimulation.layou.FlowLayout android:id="@+id/flow_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp"></com.bawei.mysimulation.layou.FlowLayout> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="查看购物车" android:id="@+id/login"/> </LinearLayout >
import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; import com.bawei.mysimulation.app.MyApplication; import com.bawei.mysimulation.bean.Person; import com.bawei.mysimulation.view.Main2Activity; import com.bawei.mysimulation.R; import com.com.sky.downloader.greendao.PersonDao; import java.util.ArrayList; import java.util.List; // _ooOoo_ // o8888888o // 88" . "88 // (| -_- |) // O\ = /O // ____/`---'\____ // . ' \\| |// `. // / \\||| : |||// \ // / _||||| -:- |||||- \ // | | \\\ - /// | | // | \_| ''\---/'' | | // \ .-\__ `-` ___/-. / // ___`. .' /--.--\ `. . __ // ."" '< `.___\_<|>_/___.' >'"". // | | : `- \`.;`\ _ /`;.`/ - ` : | | // \ \ `-. \_ __\ /__ _/ .-` / / // ======`-.____`-.___\_____/___.-`____.-'====== // `=---=' // // ......... 佛祖保佑 永无BUG .............. public class MainActivity extends AppCompatActivity implements View.OnClickListener { private FlowLayout flow_layout; private TextView tagView; private EditText mEdit; /** * 搜 */ private Button mFind; /** * 清 */ private Button mDel; List<String> list = new ArrayList<>(); private LinearLayout mActivityMain; String s; /** * 查看购物车 */ private Button mLogin; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); personDao = MyApplication.getDaoSession().getPersonDao(); initView(); } private void initView() { flow_layout = (FlowLayout) findViewById(R.id.flow_layout); mEdit = (EditText) findViewById(R.id.edit); mFind = (Button) findViewById(R.id.find); mFind.setOnClickListener(this); mDel = (Button) findViewById(R.id.del); mDel.setOnClickListener(this); mActivityMain = (LinearLayout) findViewById(R.id.activity_main); mLogin = (Button) findViewById(R.id.login); mLogin.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { default: break; case R.id.find: getview(); break; case R.id.del: //清除没做 mEdit.setText(""); break; case R.id.login: break; } } //创建布局 private void getview() { s = mEdit.getText().toString(); if (s != null & !"".equals(s)) { //添加进集合 list.add(s); mEdit.setText(""); //---------------- tagView = (TextView) getLayoutInflater().inflate(R.layout.item, flow_layout, false); ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT); lp.leftMargin = 10; lp.rightMargin = 10; lp.topMargin = 10; tagView.setLayoutParams(lp); //取集合最后一个 tagView.setText(list.get(list.size()-1)); flow_layout.addView(tagView); } } } /* * for (int i = 0; i < list.size(); i++) { tagView = (TextView) getLayoutInflater().inflate(R.layout.item, flow_layout, false); ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT); lp.leftMargin = 10; lp.rightMargin = 10; lp.topMargin = 10; tagView.setLayoutParams(lp); tagView.setText(list.get(i)); flow_layout.addView(tagView); }*/
布局 item
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="10dp" android:gravity="center" android:background="@drawable/textview_bg" android:textSize="13sp" android:textColor="#333333" > </TextView>draeable包下面新建 textview_bg.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <solid android:color="#ffffff"/> <stroke android:width="1dp" android:color="#dedede"/> <corners android:radius="20dp"/> </shape>