标签
import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; /** * 标签布局 */ public class FlowLayout extends ViewGroup { private int mViewTotalWidth; 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) { mViewTotalWidth = getMeasureSize(widthMeasureSpec, true); int height = getMeasureSize(heightMeasureSpec, false); // 测量子View for (int i = 0; i < getChildCount(); i++) { measureChild(getChildAt(i), widthMeasureSpec, heightMeasureSpec); } setMeasuredDimension(mViewTotalWidth, height); } private int getMeasureSize(int measureSpec, boolean isWidth) { int specMode = MeasureSpec.getMode(measureSpec); int size = 0; switch (specMode) { case MeasureSpec.EXACTLY: // 父容器指定size size = MeasureSpec.getSize(measureSpec); break; case MeasureSpec.AT_MOST: // 父容器未指定size // 获取父容器最大size int parentMaxSize = MeasureSpec.getSize(measureSpec); // 获取item view的总size if (isWidth) { int totalChildWidth = 0; for (int i = 0; i < getChildCount(); i++) { View curChildView = getChildAt(i); MarginLayoutParams mlp = (MarginLayoutParams) curChildView.getLayoutParams(); totalChildWidth += curChildView.getMeasuredWidth() + mlp.leftMargin + mlp.rightMargin; } size = totalChildWidth > parentMaxSize ? parentMaxSize : totalChildWidth; } else { int totalChildHeight = 0; int tempWidth = 0; int tempLineHeight = 0; for (int i = 0; i < getChildCount(); i++) { View curChildView = getChildAt(i); MarginLayoutParams mlp = (MarginLayoutParams) curChildView.getLayoutParams(); int curChildViewWidth = curChildView.getMeasuredWidth() + mlp.leftMargin + mlp.rightMargin; int curChildViewHeight = curChildView.getMeasuredHeight() + mlp.topMargin + mlp.bottomMargin; tempLineHeight = Math.max(tempLineHeight, curChildViewHeight); if (i == 0) { totalChildHeight = tempLineHeight; } else { if (tempWidth + curChildViewWidth > mViewTotalWidth) { // 超出一行 totalChildHeight += tempLineHeight; tempWidth = 0; } } tempWidth += curChildViewWidth; } size = totalChildHeight > parentMaxSize ? parentMaxSize : totalChildHeight; } break; case MeasureSpec.UNSPECIFIED: if (isWidth) { size = 300; } else { size = 200; } break; } return size; } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int viewWidth = getWidth(); int tempLeft = 0; int tempTop = 0; int curLineMaxHeight = 0; for (int i = 0; i < getChildCount(); i++) { View curChildView = getChildAt(i); MarginLayoutParams mlp = (MarginLayoutParams) curChildView.getLayoutParams(); int curChildViewWidth = curChildView.getMeasuredWidth(); int curChildViewHeight = curChildView.getMeasuredHeight(); if (tempLeft + curChildViewWidth + mlp.leftMargin + mlp.rightMargin > viewWidth) { // 超出一行 tempLeft = 0; tempTop += curLineMaxHeight; } int curLeft = tempLeft + mlp.leftMargin; int curTop = tempTop + mlp.topMargin; curChildView.layout(curLeft, curTop, curLeft + curChildViewWidth, curTop + curChildViewHeight); tempLeft += curChildViewWidth + mlp.leftMargin + mlp.rightMargin; curLineMaxHeight = Math.max(curLineMaxHeight, curChildViewHeight + mlp.topMargin + mlp.bottomMargin); } } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new MarginLayoutParams(getContext(), attrs); } }
只是展示
private void refLabelView(ArrayList<String> labels) { mLabels = labels; mCvTagContainer.removeAllViews(); if (mLabels != null && !mLabels.isEmpty()) { for (String tag : mLabels) { TextView tvTag = (TextView) LayoutInflater.from(this).inflate(R.layout.item_sign_user, mCvTagContainer, false); tvTag.setText(tag); mCvTagContainer.addView(tvTag); } } }
也可封装包含点击
可参考: http://blog.csdn.net/jdsjlzx/article/details/38129569