How can I do something like a FlowLayout in Android?

后端 未结 9 1300
情歌与酒
情歌与酒 2020-11-22 08:11

How can I do something like a FlowLayout in Android?

9条回答
  •  礼貌的吻别
    2020-11-22 08:33

    I don't have enough reputation to post a comment to Romain Guy's answer but that's where this answer should be (I created an account just to share my edit).

    Anyway, I see other people have found out his pretty cool FlowLayout solution has some issues. I could find one myself and I saw, as others, that some children were clipped. Looking in details at the algorithm it seems to be a very simple mistake in the calculation of the height. When the very last child is the one being put on a new line, then the height was not properly computed. I cleaned up a bit the computation (there was a weird use of "height" vs. currentHeight).

    The following change fixes the problem of "last child is clipped if on a new line":

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        int widthLimit = MeasureSpec.getSize(widthMeasureSpec) - getPaddingRight();
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    
        boolean growHeight = widthMode != MeasureSpec.UNSPECIFIED;
    
        int width = 0;
    
        int currentWidth = getPaddingLeft();
        int currentHeight = getPaddingTop();
    
        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, widthMeasureSpec, heightMeasureSpec);
    
            LayoutParams lp = (LayoutParams) child.getLayoutParams();
            spacing = mHorizontalSpacing;
    
            if (lp.horizontalSpacing >= 0)
            {
                spacing = lp.horizontalSpacing;
            }
    
            if (growHeight && (breakLine || ((currentWidth + child.getMeasuredWidth()) > widthLimit)))
            {               
                newLine = true;
                currentHeight += maxChildHeight + mVerticalSpacing;
    
                width = Math.max(width, currentWidth - spacing);
    
                currentWidth = getPaddingLeft();
                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();
    
        setMeasuredDimension(resolveSize(width, widthMeasureSpec),
                resolveSize(height, heightMeasureSpec));
    }
    

提交回复
热议问题