android - ScrollView 内的 FlowLayout

标签 android view scrollview flowlayout onmeasure

我正在 ScrollView 内创建一个流布局。现在我无法解决的问题是,如果 flowlayout 的高度小于 ScrollView (即 match_parent),我希望我的 flowlayout View 完全匹配 match_parent,否则高度应该是换行内容。

这是我的 onMeasure 方法。

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

    int widthLimit = MeasureSpec.getSize(widthMeasureSpec) - getPaddingRight() - mHorizontalEndSpacingView;
    int widthMode = MeasureSpec.getMode(widthMeasureSpec);

    int heightLimit = MeasureSpec.getSize(heightMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);

    boolean growHeight = widthMode != MeasureSpec.UNSPECIFIED;

    int width = 0;

    int currentWidth = getPaddingLeft() + mHorizontalStartSpacingView;
    int currentHeight = getPaddingTop() + mVerticalStartSpacingView;

    int maxChildHeight = 0;

    boolean breakLine = false;
    boolean newLine = false;
    int spacing = 0;

    final int count = getChildCount();
    for (int i = 0; i < count; i++) {
        View child = getChildAt(i);
        measureChild(child, MeasureSpec.makeMeasureSpec(widthLimit - getPaddingLeft() - mHorizontalStartSpacingView, MeasureSpec.AT_MOST), heightMeasureSpec);

        LayoutParams lp = (LayoutParams) child.getLayoutParams();
        spacing = mHorizontalCenterSpacingView;

        if (lp.horizontalSpacing > 0) {
            spacing = lp.horizontalSpacing;
        }

        if (growHeight && (breakLine || ((currentWidth + child.getMeasuredWidth()) > widthLimit))) {
            newLine = true;
            currentHeight += maxChildHeight + mVerticalCenterSpacingView;

            width = Math.max(width, currentWidth - spacing);

            currentWidth = getPaddingLeft() + mHorizontalStartSpacingView;
            maxChildHeight = 0;
        } else {
            newLine = false;
        }

        maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight());

        lp.x = currentWidth;
        lp.y = currentHeight;

        currentWidth += child.getMeasuredWidth() + spacing;

        breakLine = lp.breakLine;
    }

    if (newLine == false) {
        width = Math.max(width, currentWidth - spacing);
    }

    width += getPaddingRight();
    int height = currentHeight + maxChildHeight + getPaddingBottom() + mVerticalEndStartSpacingView;

    setMeasuredDimension(resolveSize(width, widthMeasureSpec),
            resolveSize(height, heightMeasureSpec));
}

最佳答案

已修复。下面是新的 onMeasure

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

    int widthLimit = MeasureSpec.getSize(widthMeasureSpec) - getPaddingRight() - mHorizontalEndSpacingView;
    int widthMode = MeasureSpec.getMode(widthMeasureSpec);

    int heightLimit = MeasureSpec.getSize(heightMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);

    boolean growHeight = widthMode != MeasureSpec.UNSPECIFIED;

    int width = 0;

    int currentWidth = getPaddingLeft() + mHorizontalStartSpacingView;
    int currentHeight = getPaddingTop() + mVerticalStartSpacingView;

    int maxChildHeight = 0;

    boolean breakLine = false;
    boolean newLine = false;
    int spacing = 0;

    final int count = getChildCount();
    for (int i = 0; i < count; i++) {
        View child = getChildAt(i);
        measureChild(child, MeasureSpec.makeMeasureSpec(widthLimit - getPaddingLeft() - mHorizontalStartSpacingView, MeasureSpec.AT_MOST), heightMeasureSpec);

        LayoutParams lp = (LayoutParams) child.getLayoutParams();
        spacing = mHorizontalCenterSpacingView;

        if (lp.horizontalSpacing > 0) {
            spacing = lp.horizontalSpacing;
        }

        if (growHeight && (breakLine || ((currentWidth + child.getMeasuredWidth()) > widthLimit))) {
            newLine = true;
            currentHeight += maxChildHeight + mVerticalCenterSpacingView;

            width = Math.max(width, currentWidth - spacing);

            currentWidth = getPaddingLeft() + mHorizontalStartSpacingView;

            maxChildHeight = 0;
        } else {
            newLine = false;
        }

        maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight());

        lp.x = currentWidth;
        lp.y = currentHeight;

        currentWidth += child.getMeasuredWidth() + spacing;

        breakLine = lp.breakLine;
    }

    if (newLine == false) {
        width = Math.max(width, currentWidth - spacing);
    }

    width += getPaddingRight();
    int height = currentHeight + maxChildHeight + getPaddingBottom() + mVerticalEndStartSpacingView;

    // The Fix.
    int parentViewHeight = ((ScrollView) getParent()).getHeight();
    if(parentViewHeight > height) {
        height = parentViewHeight;
    }
    // End

    int finalWidth = resolveSize(width, widthMeasureSpec);
    int finalHeight = resolveSize(height, heightMeasureSpec);
    setMeasuredDimension(finalWidth, finalHeight);
}

关于android - ScrollView 内的 FlowLayout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32367888/

相关文章:

android - 使用Gradle构建并运行tensorflow lite演示

mysql - View 和零参数过程有什么区别?

sql - 将多个 SQL 字段显示为单个字段

ios - 在 ios 6 中,如何在持有 'Container View' 对象的 View Controller 和嵌入其中的 TableView Controller 之间使用传递数据?

Android View.OnKeyListener : click once, 执行两次

android - 在 APK Android 中复制的重复文件 - 可以合并吗?

android - 折线未完成到谷歌地图上的目的地

android onclicklistener 在类里面有按钮吗?

android - Android中的ScrollView问题

android - 在android中滚动时使 ScrollView 的边缘消失