SeniorUI0202_UI绘制流程分析二应用(瀑布流)

SeniorUI02_UI绘制流程分析二(View的绘制过程)

1 Effect picture

这里写图片描述

2 Demo

WaterfallLayout

3 RequireMent

(1)瀑布流添加标签,图片或其他View均可;
(2)宽度相等,高度不定;
(3)每次添加元素加到最低高度的列上;

4 Theory

(1)自定义控件继承ViewGroup
(2) onMesure确定宽高,并记录每列高度
(3)定义一个Param,onMesure时记录每个child的位置
(4)onLayout中获取Param,设置每个child的位置

4 核心代码

onMesure:

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        //得到总宽度
        int measureWidth = 0;
        int measureHeight = 0;

        if (widthMode == MeasureSpec.EXACTLY) {
            measureWidth = widthSize;
            measureHeight = heightSize;
        } else {
            measureChildren(widthMeasureSpec, heightMeasureSpec);

            //得到单个Item的宽度
            mChildWidth = (widthSize - (mColumns - 1) * mHorizontalSpace) / mColumns;

            int childCount = getChildCount();
            if (childCount < mColumns) {
                measureWidth = childCount * mChildWidth + (childCount - 1) * mHorizontalSpace;
            } else {
                measureWidth = widthSize;
            }

            clearTop();
            for (int i = 0; i < childCount; i++) {
                View child = getChildAt(i);
                int childHeight = child.getMeasuredHeight() * mChildWidth / child.getMeasuredWidth();
                int minColum = getMinHeightColum();

                WaterfallLayoutParams lParams = (WaterfallLayoutParams) child.getLayoutParams();
                lParams.left = minColum * (mChildWidth + mHorizontalSpace);
                lParams.top = mTop[minColum];
                lParams.right = lParams.left + mChildWidth;
                lParams.bottom = lParams.top + childHeight;
                mTop[minColum] += mVerticalSpace + childHeight;
            }
            measureHeight = getMaxHeight();
        }

        setMeasuredDimension(measureWidth, measureHeight);
    }

onLayout:

@Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int childCount = getChildCount();
        clearTop();
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
            WaterfallLayoutParams params = (WaterfallLayoutParams) child.getLayoutParams();
            child.layout(params.left, params.top, params.right, params.bottom);
        }
    }

定义一个记录child位置的params

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

public static class WaterfallLayoutParams extends LayoutParams {

        public int left, top, right, bottom;

        public WaterfallLayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);
        }

        public WaterfallLayoutParams(int width, int height) {
            super(width, height);
        }

        public WaterfallLayoutParams(LayoutParams source) {
            super(source);
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值