@SuppressLint("DrawAllocation") @Override protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec){
  int widthMode=MeasureSpec.getMode(widthMeasureSpec);
  int heightMode=MeasureSpec.getMode(heightMeasureSpec);
  int maxWidth=MeasureSpec.getSize(widthMeasureSpec);
  int maxHeight=MeasureSpec.getSize(heightMeasureSpec);
  if (widthMode == MeasureSpec.UNSPECIFIED)   maxWidth=Integer.MAX_VALUE;
  if (heightMode == MeasureSpec.UNSPECIFIED)   maxHeight=Integer.MAX_VALUE;
  int paddingLeft=getPaddingLeft();
  int paddingTop=getPaddingTop();
  int paddingRight=getPaddingRight();
  int paddingBottom=getPaddingBottom();
  int maxRightBound=maxWidth - paddingRight;
  int maxBottomBound=maxHeight - paddingBottom;
  int left;
  int top;
  int right;
  int bottom;
  int rightBound=paddingLeft;
  int maxRightNoPadding=rightBound;
  int bottomBound;
  int lastMaxBottom=paddingTop;
  int maxBottom=lastMaxBottom;
  int childWidth;
  int childHeight;
  int lineStartIndex=0;
  int lineEndIndex=0;
  rectList.clear();
  int childCount=getChildCount();
  for (int index=0; index < childCount; index++) {
    final View child=getChildAt(index);
    child.measure(MeasureSpec.UNSPECIFIED,MeasureSpec.UNSPECIFIED);
    if (child.getVisibility() == View.GONE)     continue;
    final AutoWrapLayout.LayoutParams lp=(AutoWrapLayout.LayoutParams)child.getLayoutParams();
    childWidth=child.getMeasuredWidth();
    childHeight=child.getMeasuredHeight();
    left=rightBound + lp.leftMargin;
    right=left + childWidth;
    rightBound=right + lp.rightMargin;
    if (rightBound > maxRightBound) {
      lineEndIndex=index;
      adjustBaseLine(maxBottom - lastMaxBottom,lineStartIndex,lineEndIndex);
      if (maxBottom >= maxBottomBound)       break;
      if (lineEndIndex == lineStartIndex) {
        child.measure(MeasureSpec.makeMeasureSpec(maxWidth - paddingLeft - paddingRight- lp.leftMargin- lp.rightMargin,MeasureSpec.AT_MOST),MeasureSpec.UNSPECIFIED);
        childWidth=child.getMeasuredWidth();
        childHeight=child.getMeasuredHeight();
      }
      left=paddingLeft + lp.leftMargin;
      right=left + childWidth;
      rightBound=right + lp.rightMargin;
      lastMaxBottom=maxBottom;
      top=lastMaxBottom + lp.topMargin;
      bottom=top + childHeight;
      bottomBound=bottom + lp.bottomMargin;
      lineStartIndex=index;
    }
 else {
      top=lastMaxBottom + lp.topMargin;
      bottom=top + childHeight;
      bottomBound=bottom + lp.bottomMargin;
    }
    if (rightBound > maxRightNoPadding)     maxRightNoPadding=rightBound;
    if (bottomBound > maxBottom)     maxBottom=bottomBound;
    Rect rect=new Rect();
    rect.left=left;
    rect.top=top;
    rect.right=right;
    rect.bottom=bottom;
    rectList.add(rect);
  }
  adjustBaseLine(maxBottom - lastMaxBottom,lineStartIndex,rectList.size());
  int measuredWidth;
  int measuredHeight;
  if (widthMode == MeasureSpec.EXACTLY)   measuredWidth=maxWidth;
 else   measuredWidth=maxRightNoPadding + paddingRight;
  if (heightMode == MeasureSpec.EXACTLY)   measuredHeight=maxHeight;
 else {
    measuredHeight=maxBottom + paddingBottom;
    if (heightMode == MeasureSpec.AT_MOST)     measuredHeight=measuredHeight > maxHeight ? maxHeight : measuredHeight;
  }
  setMeasuredDimension(measuredWidth,measuredHeight);
}

@ SuppressLint ( "DrawAllocation" ) @ Override protected void onMeasure ( int widthMeasureSpec , int heightMeasureSpec ) { int widthMode = MeasureSpec . getMode ( widthMeasureSpec ) ; int heightMode = MeasureSpec . getMode ( heightMeasureSpec ) ; int maxWidth = MeasureSpec . getSize ( widthMeasureSpec ) ; int maxHeight = MeasureSpec . getSize ( heightMeasureSpec ) ; if ( widthMode == MeasureSpec . UNSPECIFIED ) maxWidth = Integer . MAX_VALUE ; if ( heightMode == MeasureSpec . UNSPECIFIED ) maxHeight = Integer . MAX_VALUE ; int paddingLeft = getPaddingLeft ( ) ; int paddingTop = getPaddingTop ( ) ; int paddingRight = getPaddingRight ( ) ; int paddingBottom = getPaddingBottom ( ) ; int maxRightBound = maxWidth - paddingRight ; int maxBottomBound = maxHeight - paddingBottom ; int left ; int top ; int right ; int bottom ; int rightBound = paddingLeft ; int maxRightNoPadding = rightBound ; int bottomBound ; int lastMaxBottom = paddingTop ; int maxBottom = lastMaxBottom ; int childWidth ; int childHeight ; int lineStartIndex = 0 ; int lineEndIndex = 0 ; rectList . clear ( ) ; int childCount = getChildCount ( ) ; for ( int index = 0 ; index < childCount ; index ++ ) { final View child = getChildAt ( index ) ; child . measure ( MeasureSpec . UNSPECIFIED , MeasureSpec . UNSPECIFIED ) ; if ( child . getVisibility ( ) == View . GONE ) continue ; final AutoWrapLayout . LayoutParams lp = ( AutoWrapLayout . LayoutParams ) child . getLayoutParams ( ) ; childWidth = child . getMeasuredWidth ( ) ; childHeight = child . getMeasuredHeight ( ) ; left = rightBound + lp . leftMargin ; right = left + childWidth ; rightBound = right + lp . rightMargin ; if ( rightBound > maxRightBound ) { lineEndIndex = index ; adjustBaseLine ( maxBottom - lastMaxBottom , lineStartIndex , lineEndIndex ) ; if ( maxBottom >= maxBottomBound ) break ; if ( lineEndIndex == lineStartIndex ) { child . measure ( MeasureSpec . makeMeasureSpec ( maxWidth - paddingLeft - paddingRight - lp . leftMargin - lp . rightMargin , MeasureSpec . AT_MOST ) , MeasureSpec . UNSPECIFIED ) ; childWidth = child . getMeasuredWidth ( ) ; childHeight = child . getMeasuredHeight ( ) ; } left = paddingLeft + lp . leftMargin ; right = left + childWidth ; rightBound = right + lp . rightMargin ; lastMaxBottom = maxBottom ; top = lastMaxBottom + lp . topMargin ; bottom = top + childHeight ; bottomBound = bottom + lp . bottomMargin ; lineStartIndex = index ; } else { top = lastMaxBottom + lp . topMargin ; bottom = top + childHeight ; bottomBound = bottom + lp . bottomMargin ; } if ( rightBound > maxRightNoPadding ) maxRightNoPadding = rightBound ; if ( bottomBound > maxBottom ) maxBottom = bottomBound ; Rect rect = new Rect ( ) ; rect . left = left ; rect . top = top ; rect . right = right ; rect . bottom = bottom ; rectList . add ( rect ) ; } adjustBaseLine ( maxBottom - lastMaxBottom , lineStartIndex , rectList . size ( ) ) ; int measuredWidth ; int measuredHeight ; if ( widthMode == MeasureSpec . EXACTLY ) measuredWidth = maxWidth ; else measuredWidth = maxRightNoPadding + paddingRight ; if ( heightMode == MeasureSpec . EXACTLY ) measuredHeight = maxHeight ; else { measuredHeight = maxBottom + paddingBottom ; if ( heightMode == MeasureSpec . AT_MOST ) measuredHeight = measuredHeight > maxHeight ? maxHeight : measuredHeight ; } setMeasuredDimension ( measuredWidth , measuredHeight ) ; }
each row or line at least show one child horizontal only show child can show or partly show in parent
