自定义ViewGroup详解

2018-09-18  本文已影响0人  kjy_112233

一、ViewGroup

(1)常用方法

(2)自定义属性

<resources>
    <declare-styleable name="customViewGroup">
        <attr name="horizontal_space" format="dimension"></attr>
        <attr name="vertical_space" format="dimension"></attr>
    </declare-styleable>
</resources>

(3)onMeasure与onLayout

(4)自定义ViewGroup实现

public class CustomViewGroup extends ViewGroup {

    public CustomViewGroup(Context context) {
        super(context);
    }

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

    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new MarginLayoutParams(getContext(), attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        measureChildren(widthMeasureSpec, heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        //判断当前设置是否是wrap_content
        if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST) {
            int groupWidth = getMaxWidth();
            int groupHeight = getTotalHeight();
            setMeasuredDimension(groupWidth, groupHeight);
        } else if (widthMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(getMaxWidth(), heightSize);
        } else if (heightMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(widthSize, getTotalHeight());
        }
    }

    private int getMaxWidth() {
        int count = getChildCount();
        int maxWidth = 0;
        for (int i = 0; i < count; i++) {
            int currentWidth = getChildAt(i).getMeasuredWidth();
            if (maxWidth < currentWidth)
                maxWidth = currentWidth;
        }
        return maxWidth;
    }

    private int getTotalHeight() {
        int count = getChildCount();
        int totalHeight = 0;
        for (int i = 0; i < count; i++) {
            totalHeight += getChildAt(i).getMeasuredHeight();
        }
        return totalHeight;
    }


    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int count = getChildCount();
        int currentHeight = 0;
        for (int i = 0; i < count; i++) {
            View view = getChildAt(i);
            int height = view.getMeasuredHeight();
            int width = view.getMeasuredWidth();
            view.layout(l, currentHeight, l + width, currentHeight + height);
            currentHeight += height;
        }
    }
}

(5)自定义ViewGroup自动换行

public class CustomViewGroup extends ViewGroup {
    private int count;
    //子View上方距离
    private int marginTop;
    //子View左侧距离
    private int marginLeft;
    //子View中上下的空闲区域
    private int paddingTop;
    //子View中左右的空闲区域
    private int paddingLeft;

    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);
        @SuppressLint("CustomViewStyleable")
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.customViewGroup);
        marginTop = typedArray.getDimensionPixelOffset(R.styleable.customViewGroup_vg_margin_top, 0);
        marginLeft = typedArray.getDimensionPixelOffset(R.styleable.customViewGroup_vg_margin_left, 0);
        paddingTop = typedArray.getDimensionPixelOffset(R.styleable.customViewGroup_vg_padding_top, 0);
        paddingLeft = typedArray.getDimensionPixelOffset(R.styleable.customViewGroup_vg_padding_left, 0);
        typedArray.recycle();
    }


    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new MarginLayoutParams(getContext(), attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        measureChildren(widthMeasureSpec, heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int rowNumber = 1;
        int totalWidth = 0;
        int totalHeight = 0;
        count = getChildCount();
        for (int i = 0; i < count; i++) {
            View view = getChildAt(i);
            view.setPadding(paddingLeft, paddingTop, paddingLeft, paddingTop);
            int width = view.getMeasuredWidth();
            int height = view.getMeasuredHeight();
            totalWidth += (width + marginLeft);
            if (totalWidth > widthSize) {
                totalWidth = (width + marginLeft);
                rowNumber++;
            }
            totalHeight = rowNumber * (height + marginTop);
        }
        setMeasuredDimension(widthSize, totalHeight);
    }


    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int rowNumber = 1;
        int totalWidth = 0;
        int totalHeight;
        int actualWidth = r - l;
        for (int i = 0; i < count; i++) {
            View view = getChildAt(i);
            int width = getChildAt(i).getMeasuredWidth();
            int height = getChildAt(i).getMeasuredHeight();
            totalWidth += (width + marginLeft);
            if (totalWidth > actualWidth) {
                totalWidth = (width + marginLeft);
                rowNumber++;
            }
            totalHeight = rowNumber * (height + marginTop);
            view.layout(totalWidth - width, totalHeight - height, totalWidth, totalHeight);
        }
    }
}
上一篇 下一篇

猜你喜欢

热点阅读