RecyclerView自动换行平均布局管理器

在网上找到的 AutoLineFeedLayoutManager 自动换行布局管理器(靠左布局)上做了修改,以支持
换行后实现居中布局。
效果如下图:
在这里插入图片描述
(原创作品,转载请声明出处:https://blog.csdn.net/hegan2010/article/details/113102364)

代码如下:

import android.content.Context;
import android.util.AttributeSet;
import android.util.Size;
import android.view.View;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import java.util.LinkedHashMap;
import java.util.Map;

public class AutoLineFeedLayoutManager extends LinearLayoutManager {
    
    
    public AutoLineFeedLayoutManager(Context context) {
    
    
        super(context);
        //setOrientation(RecyclerView.HORIZONTAL);
    }

    public AutoLineFeedLayoutManager(Context context, AttributeSet attrs, int defStyleAttr,
            int defStyleRes) {
    
    
        super(context, attrs, defStyleAttr, defStyleRes);
        //setOrientation(RecyclerView.HORIZONTAL);
    }

    @Override
    public RecyclerView.LayoutParams generateDefaultLayoutParams() {
    
    
        return new RecyclerView.LayoutParams(
                RecyclerView.LayoutParams.WRAP_CONTENT, RecyclerView.LayoutParams.WRAP_CONTENT);
    }

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
    
    
        onAverageLayoutChildren(recycler, state);
    }

    public void onLeftLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
    
    
        detachAndScrapAttachedViews(recycler);

        int parentWidth = getWidth();
        int curLineWidthSum = 0;
        int curLineTop = 0;
        int lastLineMaxHeight = 0;

        for (int i = 0, count = getItemCount(); i < count; i++) {
    
    
            View view = recycler.getViewForPosition(i);
            addView(view);
            measureChildWithMargins(view, 0, 0);
            int width = getDecoratedMeasuredWidth(view);
            int height = getDecoratedMeasuredHeight(view);
            curLineWidthSum += width;

            if (curLineWidthSum <= parentWidth) {
    
    
                layoutDecorated(view,
                        curLineWidthSum - width, curLineTop, curLineWidthSum, curLineTop + height);
                if (lastLineMaxHeight < height) {
    
    
                    lastLineMaxHeight = height;
                }
            } else {
    
    
                curLineWidthSum = width;
                if (lastLineMaxHeight == 0) {
    
    
                    lastLineMaxHeight = height;
                }
                curLineTop += lastLineMaxHeight;
                layoutDecorated(view, 0, curLineTop, width, curLineTop + height);
                lastLineMaxHeight = height;
            }
        }
    }

    private void onAverageLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
    
    
        detachAndScrapAttachedViews(recycler);

        int parentWidth = getWidth();
        int curLineWidthSum = 0;
        int curLineTop = 0;
        int lastLineMaxHeight = 0;

        Map<View, Size> lastLineMap = new LinkedHashMap<>();
        for (int i = 0, count = getItemCount(); i < count; i++) {
    
    
            View view = recycler.getViewForPosition(i);
            addView(view);
            measureChildWithMargins(view, 0, 0);
            int width = getDecoratedMeasuredWidth(view);
            int height = getDecoratedMeasuredHeight(view);
            curLineWidthSum += width;

            if (curLineWidthSum <= parentWidth) {
    
    
                lastLineMap.put(view, new Size(width, height));
                if (lastLineMaxHeight < height) {
    
    
                    lastLineMaxHeight = height;
                }
            } else {
    
    
                int lastLineSize = lastLineMap.size();
                if (lastLineSize > 0) {
    
    
                    int widthOffset = (parentWidth - curLineWidthSum + width) / (lastLineSize + 1);
                    int idxLeft = widthOffset;
                    for (Map.Entry<View, Size> entry : lastLineMap.entrySet()) {
    
    
                        View idxView = entry.getKey();
                        Size idxSize = entry.getValue();
                        int idxRight = idxLeft + idxSize.getWidth();
                        layoutDecorated(idxView,
                                idxLeft, curLineTop, idxRight, curLineTop + idxSize.getHeight());
                        idxLeft = idxRight + widthOffset;
                    }
                    lastLineMap.clear();
                }

                lastLineMap.put(view, new Size(width, height));
                curLineWidthSum = width;
                if (lastLineMaxHeight == 0) {
    
    
                    lastLineMaxHeight = height;
                }
                curLineTop += lastLineMaxHeight;
                lastLineMaxHeight = height;
            }
        }
        int lastLineSize = lastLineMap.size();
        if (lastLineSize > 0) {
    
    
            int widthOffset = (parentWidth - curLineWidthSum) / (lastLineSize + 1);
            int idxLeft = widthOffset;
            for (Map.Entry<View, Size> entry : lastLineMap.entrySet()) {
    
    
                View idxView = entry.getKey();
                Size idxSize = entry.getValue();
                int idxRight = idxLeft + idxSize.getWidth();
                layoutDecorated(idxView,
                        idxLeft, curLineTop, idxRight, curLineTop + idxSize.getHeight());
                idxLeft = idxRight + widthOffset;
            }
        }
        lastLineMap.clear();
    }
}

猜你喜欢

转载自blog.csdn.net/hegan2010/article/details/113102364
今日推荐