首先看效果如下
首先我们需要自定义ViewGroup 重写onMeasure和onLayout将布局摆放好然后在通过适配器添加子view
代码如下
public class MyViewGroup extends ViewGroup {
List<List<View>> childList;
public MyViewGroup(Context context) {
this(context, null);
}
public MyViewGroup(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MarginLayoutParams(getContext(), attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
childList = new ArrayList<>();
int viewWidth = MeasureSpec.getSize(widthMeasureSpec);
int viewHeight = 0;
int lineWidth = getPaddingLeft();
int count = getChildCount();
List<View> viewList = new ArrayList<>();
childList.add(viewList);
for (int i = 0; i < count; i++) {
View childView = getChildAt(i);
measureChild(childView, widthMeasureSpec, heightMeasureSpec);
MarginLayoutParams params = (MarginLayoutParams) childView.getLayoutParams();
int childWidth = childView.getMeasuredWidth() + params.leftMargin + params.rightMargin;
int childHeight = childView.getMeasuredHeight() + params.topMargin + params.bottomMargin;
if (lineWidth + childWidth > viewWidth) {//换行
viewHeight += childHeight;
lineWidth = childWidth + getPaddingLeft();
viewList = new ArrayList<>();
childList.add(viewList);
viewList.add(childView);
} else {
lineWidth += childWidth;
viewList.add(childView);
}
}
setMeasuredDimension(viewWidth, viewHeight);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int left, top = 0, right = 0, bottom = 0;
for (List<View> viewList : childList) {
left = getPaddingLeft();
for (View view : viewList) {
MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams();
left += params.leftMargin;
right = left + view.getMeasuredWidth() + params.rightMargin;
int viewTop = top + params.topMargin;
bottom = top + view.getMeasuredHeight() + params.bottomMargin;
view.layout(left, viewTop, right, bottom);
left += view.getMeasuredWidth() + params.rightMargin;
}
View child = viewList.get(0);
MarginLayoutParams params = (MarginLayoutParams) child.getLayoutParams();
top += child.getMeasuredHeight() + params.topMargin + params.bottomMargin;
}
}
public void setAdapter(MyViewGroupAdapter adapter) {
removeAllViews();
List<String> mDates = adapter.getDates();
LayoutInflater inflater = LayoutInflater.from(getContext());
for (String mDate : mDates) {
View view = inflater.inflate(R.layout.item_vg, this, false);
((TextView) view.findViewById(R.id.tv_content)).setText(mDate);
addView(view);
}
postInvalidate();
}
public interface MyViewGroupAdapter {
public List<String> getDates();
}
}
这里需要注意的使我们需要重写generateLayoutParams这个方法返回MarginLayoutParams这样我们才能通过这个类获取我们设置的margin值
最后我们需要在activity中调
代码如下
MyViewGroup vg = (MyViewGroup) findViewById(R.id.vg);
vg.setAdapter(new MyViewGroup.MyViewGroupAdapter() {
@Override
public List<String> getDates() {
List<String> dates = new ArrayList<>();
for (int i = 0; i < 20; i++) {
if (i == 9) {
dates.add("sssssssssskkkkkss22222ssssssssssssssssssssss");
}
dates.add("---test---->" + i);
}
return dates;
}
});
item_vg的代码如下
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:background="@drawable/rountbg"
android:padding="5dp"
android:layout_margin="5dp"
android:layout_height="wrap_content"
android:orientation="vertical"/>
activity中调用代码如下
<com.mvvm.MyViewGroup
android:id="@+id/vg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#00ffff"/>