流失布局

本文详细解析了自定义FlowLayout布局的实现原理与过程。通过继承ViewGroup类,该布局能够根据子视图数量动态调整布局方式,实现水平方向上的灵活布局效果。文中深入介绍了onMeasure与onLayout方法的具体实现细节,包括如何测量子视图尺寸、如何计算布局位置等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public class FlowLayout extends ViewGroup {


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

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

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


    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //配置初始宽度
        measureChildren(widthMeasureSpec,heightMeasureSpec);
        int widthSize=MeasureSpec.getSize(widthMeasureSpec);
        int widthMode=MeasureSpec.getMode(widthMeasureSpec);
        int heightSize=MeasureSpec.getSize(heightMeasureSpec);
        int heightMode=MeasureSpec.getMode(heightMeasureSpec);

        //定义属性
        int height =0;
        int width=0;
        int totalHeight=0;
        View childView;
        int lineWidth=0;
        int childWidth=0;
        int childHeight=0;

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

        }
        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 totalHeight=0;
        View childView;
        int lineWidth=0;
        int childWidth=0;
        int childHeight=0;
        int lineHeight=0;
        for (int i = 0; i <getChildCount() ; i++) {
            childView=getChildAt(i);
            childWidth =childView.getMeasuredWidth();
            childHeight =childView.getMeasuredHeight();
            MarginLayoutParams marginLayoutParams= (MarginLayoutParams) childView.getLayoutParams();

            int leftMargin=  marginLayoutParams.leftMargin;
            int rightMargin=  marginLayoutParams.rightMargin;
            int TopMargin=  marginLayoutParams.topMargin;
            int BottomMargin=  marginLayoutParams.bottomMargin;
            if (i %2 ==0){
                lineWidth =leftMargin;
                totalHeight+=lineHeight+TopMargin+BottomMargin;
                getViewLayout(childView,lineWidth,totalHeight,lineWidth+childWidth+rightMargin,totalHeight+childHeight );
                lineHeight =childHeight+TopMargin+BottomMargin;
                lineWidth =childWidth+leftMargin+rightMargin;
                totalHeight += lineHeight;
            }else{
                getViewLayout(childView,lineWidth+leftMargin,totalHeight,lineWidth+childWidth+rightMargin,totalHeight+childHeight );
            }
        }
    }


    private void getViewLayout(View childView, int lineWidth, int totalHeight, int i, int i1) {
        childView.layout(lineWidth,totalHeight,i,i1);
    }

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

    @Override
    protected LayoutParams generateDefaultLayoutParams() {
        return new MarginLayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);

    }

    @Override
    protected LayoutParams generateLayoutParams(LayoutParams p) {
        return new MarginLayoutParams(p);
    }


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值