How to reset only one subview in onMeasure so that one row fills the screen, if there are multiple adaptive rows

How to reset only one subview in onMeasure so that one row fills the screen, if there are multiple adaptive rows

You can try to override the or method in onMeasurethe method to achieve this requirement.measureChildWithMarginsmeasureChild

For a View with only one word, we can set its width to the screen width and its height to the maximum height, so that the View will fill a whole row.

For multiple View adaptive situations, we can first measure the width of each View and add up to get their total width. If the total width is less than the screen width, then we can set the width of the View to the screen width divided by the number of Views, so that the width of all Views is the same and can be placed in one line. Otherwise, we can default to laying out the original width and let them be divided into multiple lines.

Here is sample code:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    // 获取父容器的尺寸规格
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    int childCount = getChildCount();
    if (childCount == 1) {  // 只有一个 View 的情况
        View child = getChildAt(0);

        // 让 View 的宽度填满屏幕,高度取最大值
        int widthMeasureSpecForChild = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
        int heightMeasureSpecForChild = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        child.measure(widthMeasureSpecForChild, heightMeasureSpecForChild);

        setMeasuredDimension(widthSize, child.getMeasuredHeight());
    } else {  // 多个 View 的情况
        int totalWidth = 0;

        // 计算多个 View 的总宽度
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);

            int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
            int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
            child.measure(childWidthMeasureSpec, childHeightMeasureSpec);

            int childWidth = child.getMeasuredWidth();
            totalWidth += childWidth;
        }

        // 如果总宽度小于屏幕宽度,让每一个 View 的宽度都为屏幕宽度除以 View 的个数
        if (totalWidth < widthSize) {
            for (int i = 0; i < childCount; i++) {
                View child = getChildAt(i);

                int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize / childCount, MeasureSpec.EXACTLY);
                int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
                child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
            }
        }

        // 测量自身尺寸并设置
        int totalHeight = 0;
        int lineWidth = 0;
        int lineHeight = 0;
        int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);

            // 测量子 View 的尺寸
            child.measure(childWidthMeasureSpec, childHeightMeasureSpec);

            // 计算子 View 的行宽和行高
            int childWidth = child.getMeasuredWidth();
            int childHeight = child.getMeasuredHeight();
            if (lineWidth + childWidth > widthSize) {
                totalHeight += lineHeight;
                lineWidth = 0;
                lineHeight = childHeight;
            }
            lineWidth += childWidth;
            lineHeight = Ma

Guess you like

Origin blog.csdn.net/ck3345143/article/details/130429121