流失布局

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

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

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

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    //测量所有孩子的宽高
    measureChildren(widthMeasureSpec, heightMeasureSpec);
    //最大的宽度,也就是FlowLayout父布局的宽度
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);

    int width = 0;
    int height = 0;
    int lineWidth = 0;
    int lineHeight = 0;
    int totalHeight = 0;
    View childView;
    int childWidth = 0;
    int childHeight = 0;

    for (int i = 0; i < getChildCount(); i++) {
        childView = getChildAt(i);
        childWidth = childView.getMeasuredWidth();

        if (childWidth > widthSize) {
            throw new IllegalArgumentException("子view宽度不能大于FlowLayout宽度");
        }

        childHeight = childView.getMeasuredHeight();
        if (lineWidth + childWidth > widthSize) {
            //换行width就是最大宽,只要又换行的情况出现,说明流式布局的宽度已经不够用了
            width = widthSize;
            //totalHeight不包含最后一行高度
            int preLineHeight = lineHeight;
            totalHeight += preLineHeight;
            lineHeight = childHeight;
            lineWidth = childWidth;

        } else {
            //不换行
            lineWidth += childWidth;
            //当前行的高度
            lineHeight = Math.max(lineHeight, childHeight);

            //假如只有一行,那测量的宽度就是当前行宽,如果又换行那就去最大宽
            width = Math.max(width, lineWidth);
        }

        //当结束遍历的时候要加上最后一行的高度
        if (i == getChildCount() - 1) {
            totalHeight += lineHeight;
            height = totalHeight;
        }

    }

    width = widthMode == MeasureSpec.EXACTLY ? widthSize : width;
    height = heightMode == MeasureSpec.EXACTLY ? heightSize : height;

    //确定最终测量的宽高
    setMeasuredDimension(width, height);
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    int lineWidth = 0;
    int lineHeight = 0;
    int totalHeight = 0;
    View childView;
    int childWidth = 0;
    int childHeight = 0;

    for (int i = 0; i < getChildCount(); i++) {
        childView = getChildAt(i);
        childWidth = childView.getMeasuredWidth();
        childHeight = childView.getMeasuredHeight();
        if (lineWidth + childWidth > getMeasuredWidth()) {
            //换行
            //totalHeight不包含最后一行高度
            totalHeight += childHeight;
            lineWidth = 0;
            layoutChildView(childView, lineWidth, totalHeight, lineWidth + childWidth, totalHeight + childHeight);

            //换行width就是最大宽
            lineHeight = childHeight;
            lineWidth = childWidth;
        } else {
            //不换行
            layoutChildView(childView, lineWidth, totalHeight, lineWidth + childWidth, totalHeight + childHeight);
            lineWidth += childWidth;
            //当前行的高度
            lineHeight = Math.max(lineHeight, childHeight);
        }
    }

}

public void layoutChildView(View child, int l, int t, int r, int b) {
    child.layout(l, t, r, b);
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦想不上班

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值