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