自定义ViewGroup实现控件自动换行

首先看效果如下
自定义ViewGroup
首先我们需要自定义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"/>

猜你喜欢

转载自blog.csdn.net/u011048906/article/details/79358623