FlowLayout(二)

FlowLayout主要实现了onMeasure

//先测量子view然后再测量自己的view
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    Log.d(TAG,"onMeasure widthMeasureSpec :" + widthMeasureSpec + " heightMeasureSpec :" +heightMeasureSpec ) ;
    //参考framelayout ,根据view的生命周期,初始化参数应该在onMeasure,
    initMeasureParams();

    int childCount = getChildCount();
    //解析.xml,获得viewGroup的宽度和高度,mode
    int selfWidth = MeasureSpec.getSize(widthMeasureSpec);
    int selfHeight = MeasureSpec.getSize(heightMeasureSpec);
    final boolean measureMatchParentChildren = MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY ||
            MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY;

    List<View> lineViews = new ArrayList<>(); //保存一行中的所有的view
    int lineWidthUsed = 0; //记录这行已经使用了多宽的size
    int lineHeight = 0; // 一行的行高

    int parentNeededWidth = 0;  // measure过程中,子View要求的父ViewGroup的宽
    int parentNeededHeight = 0; // measure过程中,子View要求的父ViewGroup的高
    Log.i(TAG," childCount: " + childCount + " selfWidth:" + selfWidth + " selfHeight :" + selfHeight );
    for(int i = 0; i< childCount;i++) {
        View childView = getChildAt(i);
        final  MarginLayoutParams childLW =( MarginLayoutParams) childView.getLayoutParams();
        Log.i(TAG, "childview:" + childView);
        //测量子view
        int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, getPaddingLeft() + getPaddingRight() + childLW.leftMargin + childLW.rightMargin , childLW.width);
        int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,  getPaddingTop()+ getPaddingBottom() +childLW.topMargin + childLW.bottomMargin, childLW.height);
        childView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
        //获取子view的高度和宽度,需要用getMeausureWidth,这个是测量后值就存在了
        int childMeasureWidth = childView.getMeasuredWidth();
        Log.i(TAG, "childMeasureWidth :" + childMeasureWidth);
        int childMeausreHeight = childView.getMeasuredHeight();
        Log.i(TAG, "childMeausreHeight :" + childMeausreHeight);
        //通过宽度来判断是否需要换行,如果需要换行后的每行的行高来获取整个viewGroup的高度
        if (childMeasureWidth + lineWidthUsed + mHorizontalSpacing > selfWidth) {
            allLines.add(lineViews);
            lineHeights.add(lineHeight);

            //当行的宽度和高度
            parentNeededWidth = Math.max(parentNeededWidth, lineWidthUsed + mHorizontalSpacing);
            parentNeededHeight = parentNeededHeight + lineHeight + mVerticalSpacing;

            //换行后恢复所有的数据
            lineViews = new ArrayList<>();
            lineWidthUsed = 0;
            lineHeight = 0;
        }
        // lineViews是记录每行的view ,这样方便layout
        lineViews.add(childView);
        //记录每一行使用的宽度
        lineWidthUsed = childMeasureWidth + mHorizontalSpacing + lineWidthUsed;
        //记录每一行的高度
        lineHeight = Math.max(childMeausreHeight, lineHeight);
        Log.i(TAG, " lineWidthUsed :" + lineWidthUsed + " lineHeight:" + lineHeight);

        //边界处理,最后一行处理,因为最后一行的数据不会满足换行的条件呢,因此需要考虑此情况
        if(i == childCount -1)
        {
            allLines.add(lineViews);
            lineHeights.add(lineHeight);
            //当行的宽度和高度
            parentNeededWidth = Math.max(parentNeededWidth, lineWidthUsed + mHorizontalSpacing);
            parentNeededHeight = parentNeededHeight + lineHeight + mVerticalSpacing;
        }

    }

        int realWidth = measureMatchParentChildren ? selfWidth : parentNeededWidth;
        int realHeight = measureMatchParentChildren? selfHeight: parentNeededHeight;
        setMeasuredDimension(realWidth,realHeight);
}

onMeasure先测量子view然后测量自己,主要的知识点和出现的错误为:

1.通过调用getChildMeasureSpec方法将LayoutParmes转换为measureSpec,然后调用Measure方法来测量子view

2.如何换行,换行的条件

3.当需要获得子view的宽度和高度 ,调用 getMeasuredWidth,getMeasuredHeight,主要此值在onMeasure的时候获得

4.需要考虑边缘情况,最后一行的情况

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值