欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android自定义控件:绘制ViewGroup控件

程序员文章站 2022-06-08 17:07:56
...

自定义布局ViewGroup:基本操作由四个函数完成:onMeasure()、onSizeChanged()、onLayout()、dispatchDraw()。
onMeasure
测量所有子控件的尺寸(触发所有子View的onMeasure方法测量自己并把测量结果回传给ViewGroup)和设置自己的尺寸。(所有子View测量完毕后,再调用setMeasuredDimension将ViewGroup自身的宽和高传给它的父View)getChildCount()方法,返回子View的数量,measureChild()方法,调用子View的测量方法。

onSizeChanged
在onMeasure()后执行,只有大小发生了变化才会执行onSizeChange

onLayout
排列所有子View的位置,通过getChildCount()获取所有子view,getChildAt获取childView调用各自的layout(int, int, int, int)方法来排列自己。

简单实现自动换行

public class CustomViewGroup extends ViewGroup {
    private final int PADDING_HOR = 10;
    private final int PADDING_VERTICAL = 20;
    //父控件的宽度
    private int parentWidth;
    private int coordinateX;
    private int coordinateY;
    //总行数
    private int number;

    public CustomViewGroup(Context context) {
        this(context, null);
    }

    public CustomViewGroup(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        coordinateX = 0;
        coordinateY = 0;
        number = 1;
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
            if (child.getVisibility() != View.GONE) {
                child.setBackgroundColor(Color.RED);
                int width = child.getMeasuredWidth();
                int height = child.getMeasuredHeight();
                coordinateX += width;
                if (coordinateX > parentWidth) {
                    coordinateX = width;
                    number++;
                }
                coordinateY = number * height;
                child.layout(coordinateX - width, coordinateY - height, coordinateX, coordinateY);
            }
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        coordinateX = 0;
        coordinateY = 0;
        number = 1;
        parentWidth = measureSize(widthMeasureSpec, 240);
        int count = getChildCount();//子View数量
        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            if (child.getVisibility() != View.GONE) {
                child.setPadding(PADDING_HOR, PADDING_VERTICAL, PADDING_HOR, PADDING_VERTICAL);
                child.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
                measureChild(child, widthMeasureSpec, heightMeasureSpec);
                int width = child.getMeasuredWidth();
                int height = child.getMeasuredHeight();
                coordinateX += width;
                if (coordinateX > parentWidth) {//换行
                    coordinateX = width;
                    number++;
                }
                coordinateY = number * (height);
            }
        }
        setMeasuredDimension(parentWidth, coordinateY);
    }

    /**
     * 计算父控件宽度
     *
     * @param measureSpec
     * @param defaultSize
     * @return
     */
    private int measureSize(int measureSpec, int defaultSize) {
        int mode = MeasureSpec.getMode(measureSpec);
        int size = MeasureSpec.getSize(measureSpec);
        int result = defaultSize;
        if (mode == MeasureSpec.EXACTLY) {
            result = size;
        } else if (mode == MeasureSpec.AT_MOST) {
            result = Math.max(size, result);
        }
        return result;
    }
}
        arrayList.add("张三");
        arrayList.add("测试测试测试测试测试测试");
        arrayList.add("李四");
        arrayList.add("测试测试测试测试测试测试测试测试测试测试测试测试");
        arrayList.add("王五");
        arrayList.add("测试测试测试测");
        arrayList.add("赵六");
        for (int i = 0; i < arrayList.size(); i++) {
            textView = new TextView(this);
            textView.setId(i);
            textView.setText(arrayList.get(i));
            customViewGroup.addView(textView);
        }