Просто настройте ViewGroup, переопределив onLayout и метод onMeasure:
String[] dataList;
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childCount = getChildCount();
int curItemWidth, curItemHeight, curLeft, curTop, maxHeight;
//get the available size of child view
int viewLeft = this.getPaddingLeft();
int viewTop = this.getPaddingTop();
int viewRight = this.getMeasuredWidth() - this.getPaddingRight();
int viewBottom = this.getMeasuredHeight() - this.getPaddingBottom();
int viewWidth = viewRight - viewLeft;
int viewHeight = viewBottom - viewTop;
maxHeight = 0;
curLeft = viewLeft + getCurLeft(0, viewWidth, viewHeight, viewRight);
curTop = viewTop;
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (child.getVisibility() == GONE)
continue;
//Get the maximum size of the child
child.measure(MeasureSpec.makeMeasureSpec(viewWidth, MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(viewHeight, MeasureSpec.AT_MOST));
curItemWidth = child.getMeasuredWidth();
curItemHeight = child.getMeasuredHeight();
//wrap is reach to the end
if (curLeft + curItemWidth >= viewRight) { //new row
curLeft = viewLeft + getCurLeft(i, viewWidth, viewHeight, viewRight);
curTop += maxHeight;
maxHeight = 0;
}
//do the layout
child.layout(curLeft, curTop, curLeft + curItemWidth, curTop + curItemHeight);
//store the max height
maxHeight = Math.max(maxHeight, curItemHeight);
curLeft += curItemWidth;
}
}
private int getCurLeft(int currentPosition, int viewWidth, int viewHeight, int viewRight) {
int childCount = getChildCount();
int currentMaxWidth = 0;
for (int i = currentPosition; i < childCount; i++) {
View child = getChildAt(i);
if (child.getVisibility() == GONE)
continue;
child.measure(MeasureSpec.makeMeasureSpec(viewWidth, MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(viewHeight, MeasureSpec.AT_MOST));
currentMaxWidth += child.getMeasuredWidth();
//wrap is reach to the end
if (currentMaxWidth >= viewRight) { //new row
return 0;
}
}
return (viewWidth - currentMaxWidth) / 2;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Measurement will ultimately be computing these values.
int childCount = getChildCount();
int maxHeight = 0;
int maxWidth = 0;
int childState = 0;
int currentRowWidth = 0;
int parentWidth = resolveSizeAndState(maxWidth, widthMeasureSpec, childState);
// Iterate through all children, measuring them and computing our dimensions
// from their size.
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (child.getVisibility() == GONE)
continue;
// Measure the child.
measureChild(child, widthMeasureSpec, heightMeasureSpec);
maxWidth = Math.max(maxWidth, child.getMeasuredWidth());
maxHeight = Math.max(maxHeight, child.getMeasuredHeight());
currentRowWidth += child.getMeasuredWidth();
if (currentRowWidth >= parentWidth) { //create new row.
maxHeight += child.getMeasuredHeight();
currentRowWidth = 0;
}
childState = combineMeasuredStates(childState, child.getMeasuredState());
}
// Check against our minimum height and width
maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
// Report our final dimensions.
setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
resolveSizeAndState(maxHeight, heightMeasureSpec, childState << MEASURED_HEIGHT_STATE_SHIFT));
}
public void setData(String[] dataList) {
this.dataList = dataList;
for (int i = 0; i < dataList.length; i++) {
View tagView = layoutInflater.inflate(R.layout.item_tag_layout, null, false);
TextView tagTextView = tagView.findViewById(R.id.label);
tagTextView.setText(dataList[i]);
tagTextView.setTag(i);
tagTextView.setOnClickListener(onClickListener);
if (dataList[i].equalsIgnoreCase(defaultItem)) {
selectedItemView = tagTextView;
tagTextView.setTextColor(ContextCompat.getColor(getContext(), R.color.tag_layout_text_selected));
} else {
tagTextView.setTextColor(ContextCompat.getColor(getContext(), R.color.tag_layout_text_default));
}
if (i == dataList.length - 1) {
View indicator = tagView.findViewById(R.id.indicator);
indicator.setVisibility(GONE);
}
this.addView(tagView);
}
}