private void layoutVertical(boolean isRtl, boolean fromBottomToTop, int left, int top,
            int right, int bottom) {
        int paddingTop = getPaddingTop();
        int paddingBottom = getPaddingBottom();

        int paddingRight = getPaddingRight();
        int childLeft = getPaddingLeft();
        int currentViewIndex = 0;

        int width = right - left;
        int height = bottom - top;
        // childRight is used if the mFlexWrap is FLEX_WRAP_WRAP_REVERSE otherwise
        // childLeft is used to align the horizontal position of the children views.
        int childRight = width - paddingRight;

        // Use float to reduce the round error that may happen in when justifyContent ==
        // SPACE_BETWEEN or SPACE_AROUND
        float childTop;

        // Used only for if the direction is from bottom to top
        float childBottom;

        for (int i = 0, size = mFlexLines.size(); i < size; i++) {
            FlexLine flexLine = mFlexLines.get(i);
            if (hasDividerBeforeFlexLine(i)) {
                childLeft += mDividerVerticalWidth;
                childRight -= mDividerVerticalWidth;
            }
            float spaceBetweenItem = 0f;
            switch (mJustifyContent) {
                case JUSTIFY_CONTENT_FLEX_START:
                    childTop = paddingTop;
                    childBottom = height - paddingBottom;
                    break;
                case JUSTIFY_CONTENT_FLEX_END:
                    childTop = height - flexLine.mMainSize + paddingBottom;
                    childBottom = flexLine.mMainSize - paddingTop;
                    break;
                case JUSTIFY_CONTENT_CENTER:
                    childTop = paddingTop + (height - flexLine.mMainSize) / 2f;
                    childBottom = height - paddingBottom - (height - flexLine.mMainSize) / 2f;
                    break;
                case JUSTIFY_CONTENT_SPACE_AROUND:
                    int visibleCount = flexLine.getItemCountNotGone();
                    if (visibleCount != 0) {
                        spaceBetweenItem = (height - flexLine.mMainSize)
                                / (float) visibleCount;
                    }
                    childTop = paddingTop + spaceBetweenItem / 2f;
                    childBottom = height - paddingBottom - spaceBetweenItem / 2f;
                    break;
                case JUSTIFY_CONTENT_SPACE_BETWEEN:
                    childTop = paddingTop;
                    int visibleItem = flexLine.getItemCountNotGone();
                    float denominator = visibleItem != 1 ? visibleItem - 1 : 1f;
                    spaceBetweenItem = (height - flexLine.mMainSize) / denominator;
                    childBottom = height - paddingBottom;
                    break;
                default:
                    throw new IllegalStateException(
                            "Invalid justifyContent is set: " + mJustifyContent);
            }
            spaceBetweenItem = Math.max(spaceBetweenItem, 0);

            for (int j = 0; j < flexLine.mItemCount; j++) {
                View child = getReorderedChildAt(currentViewIndex);
                if (child == null) {
                    continue;
                } else if (child.getVisibility() == View.GONE) {
                    currentViewIndex++;
                    continue;
                }
                LayoutParams lp = ((LayoutParams) child.getLayoutParams());
                childTop += lp.topMargin;
                childBottom -= lp.bottomMargin;
                if (hasDividerBeforeChildAtAlongMainAxis(currentViewIndex, j)) {
                    childTop += mDividerHorizontalHeight;
                    childBottom -= mDividerHorizontalHeight;
                }
                if (isRtl) {
                    if (fromBottomToTop) {
                        layoutSingleChildVertical(child, flexLine, true, mAlignItems,
                                childRight - child.getMeasuredWidth(),
                                Math.round(childBottom) - child.getMeasuredHeight(), childRight,
                                Math.round(childBottom));
                    } else {
                        layoutSingleChildVertical(child, flexLine, true, mAlignItems,
                                childRight - child.getMeasuredWidth(), Math.round(childTop),
                                childRight, Math.round(childTop) + child.getMeasuredHeight());
                    }
                } else {
                    if (fromBottomToTop) {
                        layoutSingleChildVertical(child, flexLine, false, mAlignItems,
                                childLeft, Math.round(childBottom) - child.getMeasuredHeight(),
                                childLeft + child.getMeasuredWidth(), Math.round(childBottom));
                    } else {
                        layoutSingleChildVertical(child, flexLine, false, mAlignItems,
                                childLeft, Math.round(childTop),
                                childLeft + child.getMeasuredWidth(),
                                Math.round(childTop) + child.getMeasuredHeight());
                    }
                }
                childTop += child.getMeasuredHeight() + spaceBetweenItem + lp.bottomMargin;
                childBottom -= child.getMeasuredHeight() + spaceBetweenItem + lp.topMargin;
                currentViewIndex++;

                flexLine.mLeft = Math.min(flexLine.mLeft, child.getLeft() - lp.leftMargin);
                flexLine.mTop = Math.min(flexLine.mTop, child.getTop() - lp.topMargin);
                flexLine.mRight = Math.max(flexLine.mRight, child.getRight() + lp.rightMargin);
                flexLine.mBottom = Math.max(flexLine.mBottom, child.getBottom() + lp.bottomMargin);
            }
            childLeft += flexLine.mCrossSize;
            childRight -= flexLine.mCrossSize;
        }
    }
Sub method for {@link #onLayout(boolean, int, int, int, int)} when the
{@link #mFlexDirection} is either {@link #FLEX_DIRECTION_COLUMN} or
{@link #FLEX_DIRECTION_COLUMN_REVERSE}.

@param isRtl           {@code true} if the horizontal layout direction is right to left,
                       {@code false}
                       otherwise
@param fromBottomToTop {@code true} if the layout direction is bottom to top, {@code false}
                       otherwise
@param left            the left position of this View
@param top             the top position of this View
@param right           the right position of this View
@param bottom          the bottom position of this View
@see #getFlexWrap()
@see #setFlexWrap(int)
@see #getJustifyContent()
@see #setJustifyContent(int)
@see #getAlignItems()
@see #setAlignItems(int)
@see LayoutParams#alignSelf
common/src/main/java/com/sxjs/common/widget/flexboxlayout/FlexboxLayout.java