private void newLine() { if (mLine != null && mLine.size() > 0 && !mLines.contains(mLine)) { mLines.add(mLine); } mLine = new Line(); mCurrentWidth = 0; }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); // 布局区域 childrenWidth = widthSize - getPaddingLeft() - getPaddingRight(); int childrenHeight = heightSize - getPaddingTop() - getPaddingBottom(); reset(); for (int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); if (child.getVisibility() == View.GONE) { continue; } int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec( widthSize, widthMode == MeasureSpec.EXACTLY ? MeasureSpec.AT_MOST : widthMode); int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec( heightSize, heightMode == MeasureSpec.EXACTLY ? MeasureSpec.AT_MOST : heightMode); child.measure(childWidthMeasureSpec, childHeightMeasureSpec); if (mLine == null) { mLine = new Line(); } int measuredWidth = child.getMeasuredWidth(); // 子View最大宽度不超过内容区域 if (measuredWidth > childrenWidth) { child.measure( MeasureSpec.makeMeasureSpec(childrenWidth, MeasureSpec.EXACTLY), childHeightMeasureSpec); } mCurrentWidth += measuredWidth; // 不超过一行 if (mCurrentWidth <= childrenWidth) { mLine.addView(child); mCurrentWidth += mHorizontalSpacing; // 加上间距后超过一行 if (mCurrentWidth >= childrenWidth) { newLine(); } // 超过一行 } else { if (mLine.size() == 0) { mLine.addView(child); newLine(); } else { newLine(); mLine.addView(child); mCurrentWidth += child.getMeasuredWidth() + mHorizontalSpacing; } } // 把最后一行加到集合里 } if (mLine != null && mLine.size() > 0) { mLines.add(mLine); } int totelHeight = 0; if (heightMode == MeasureSpec.EXACTLY) { totelHeight = heightSize; } else if (heightMode == MeasureSpec.AT_MOST) { for (int i = 0; i < mLines.size(); i++) { int lineHeight = mLines.get(i).getLineHeight(); totelHeight += lineHeight; if (i != 0) { totelHeight += mVerticalSpacing; } } totelHeight = Math.min(childrenHeight, totelHeight); } setMeasuredDimension(widthSize, totelHeight + getPaddingTop() + getPaddingBottom()); }