private int expandFlexItems(int widthMeasureSpec, int heightMeasureSpec, FlexLine flexLine,
            @FlexDirection int flexDirection, int maxMainSize, int paddingAlongMainAxis,
            int startIndex, boolean calledRecursively) {
        int childIndex = startIndex;
        if (flexLine.mTotalFlexGrow <= 0 || maxMainSize < flexLine.mMainSize) {
            childIndex += flexLine.mItemCount;
            return childIndex;
        }
        int sizeBeforeExpand = flexLine.mMainSize;
        boolean needsReexpand = false;
        float unitSpace = (maxMainSize - flexLine.mMainSize) / flexLine.mTotalFlexGrow;
        flexLine.mMainSize = paddingAlongMainAxis + flexLine.mDividerLengthInMainSize;

        // Setting the cross size of the flex line as the temporal value since the cross size of
        // each flex item may be changed from the initial calculation
        // (in the measureHorizontal/measureVertical method) even this method is part of the main
        // size determination.
        // E.g. If a TextView's layout_width is set to 0dp, layout_height is set to wrap_content,
        // and layout_flexGrow is set to 1, the TextView is trying to expand to the vertical
        // direction to enclose its content (in the measureHorizontal method), but
        // the width will be expanded in this method. In that case, the height needs to be measured
        // again with the expanded width.
        if (!calledRecursively) {
            flexLine.mCrossSize = Integer.MIN_VALUE;
        }
        int largestCrossSize = 0;
        float accumulatedRoundError = 0;
        for (int i = 0; i < flexLine.mItemCount; i++) {
            View child = getReorderedChildAt(childIndex);
            if (child == null) {
                continue;
            } else if (child.getVisibility() == View.GONE) {
                childIndex++;
                continue;
            }
            LayoutParams lp = (LayoutParams) child.getLayoutParams();
            if (isMainAxisDirectionHorizontal(flexDirection)) {
                // The direction of the main axis is horizontal
                if (!mChildrenFrozen[childIndex]) {
                    float rawCalculatedWidth = child.getMeasuredWidth() + unitSpace * lp.flexGrow;
                    if (i == flexLine.mItemCount - 1) {
                        rawCalculatedWidth += accumulatedRoundError;
                        accumulatedRoundError = 0;
                    }
                    int newWidth = Math.round(rawCalculatedWidth);
                    if (newWidth > lp.maxWidth) {
                        // This means the child can't expand beyond the value of the maxWidth attribute.
                        // To adjust the flex line length to the size of maxMainSize, remaining
                        // positive free space needs to be re-distributed to other flex items
                        // (children views). In that case, invoke this method again with the same
                        // startIndex.
                        needsReexpand = true;
                        newWidth = lp.maxWidth;
                        mChildrenFrozen[childIndex] = true;
                        flexLine.mTotalFlexGrow -= lp.flexGrow;
                    } else {
                        accumulatedRoundError += (rawCalculatedWidth - newWidth);
                        if (accumulatedRoundError > 1.0) {
                            newWidth += 1;
                            accumulatedRoundError -= 1.0;
                        } else if (accumulatedRoundError < -1.0) {
                            newWidth -= 1;
                            accumulatedRoundError += 1.0;
                        }
                    }
                    int childHeightMeasureSpec = getChildHeightMeasureSpec(heightMeasureSpec, lp);
                    child.measure(MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY),
                            childHeightMeasureSpec);
                    largestCrossSize = Math.max(largestCrossSize, child.getMeasuredHeight()
                            + lp.topMargin + lp.bottomMargin);
                }
                flexLine.mMainSize += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
            } else {
                // The direction of the main axis is vertical
                if (!mChildrenFrozen[childIndex]) {
                    float rawCalculatedHeight = child.getMeasuredHeight() + unitSpace * lp.flexGrow;
                    if (i == flexLine.mItemCount - 1) {
                        rawCalculatedHeight += accumulatedRoundError;
                        accumulatedRoundError = 0;
                    }
                    int newHeight = Math.round(rawCalculatedHeight);
                    if (newHeight > lp.maxHeight) {
                        // This means the child can't expand beyond the value of the maxHeight
                        // attribute.
                        // To adjust the flex line length to the size of maxMainSize, remaining
                        // positive free space needs to be re-distributed to other flex items
                        // (children views). In that case, invoke this method again with the same
                        // startIndex.
                        needsReexpand = true;
                        newHeight = lp.maxHeight;
                        mChildrenFrozen[childIndex] = true;
                        flexLine.mTotalFlexGrow -= lp.flexGrow;
                    } else {
                        accumulatedRoundError += (rawCalculatedHeight - newHeight);
                        if (accumulatedRoundError > 1.0) {
                            newHeight += 1;
                            accumulatedRoundError -= 1.0;
                        } else if (accumulatedRoundError < -1.0) {
                            newHeight -= 1;
                            accumulatedRoundError += 1.0;
                        }
                    }
                    int childWidthMeasureSpec = getChildWidthMeasureSpec(widthMeasureSpec, lp);
                    child.measure(childWidthMeasureSpec,
                            MeasureSpec.makeMeasureSpec(newHeight, MeasureSpec.EXACTLY));
                    largestCrossSize = Math.max(largestCrossSize, child.getMeasuredWidth()
                            + lp.leftMargin + lp.rightMargin);
                }
                flexLine.mMainSize += child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
            }
            flexLine.mCrossSize = Math.max(flexLine.mCrossSize, largestCrossSize);
            childIndex++;
        }

        if (needsReexpand && sizeBeforeExpand != flexLine.mMainSize) {
            // Re-invoke the method with the same startIndex to distribute the positive free space
            // that wasn't fully distributed (because of maximum length constraint)
            expandFlexItems(widthMeasureSpec, heightMeasureSpec, flexLine, flexDirection,
                    maxMainSize, paddingAlongMainAxis, startIndex, true);
        }
        return childIndex;
    }
Expand the flex items along the main axis based on the individual flexGrow attribute.

@param widthMeasureSpec     the horizontal space requirements as imposed by the parent
@param heightMeasureSpec    the vertical space requirements as imposed by the parent
@param flexLine             the flex line to which flex items belong
@param flexDirection        the flexDirection value for this FlexboxLayout
@param maxMainSize          the maximum main size. Expanded main size will be this size
@param paddingAlongMainAxis the padding value along the main axis
@param startIndex           the start index of the children views to be expanded. This index
                            needs to
                            be an absolute index in the flex container (FlexboxLayout),
                            not the relative index in the flex line.
@param calledRecursively    true if this method is called recursively, false otherwise
@return the next index, the next flex line's first flex item starts from the returned index
@see #getFlexDirection()
@see #setFlexDirection(int)
@see LayoutParams#flexGrow
common/src/main/java/com/sxjs/common/widget/flexboxlayout/FlexboxLayout.java