Aspsine / IRecyclerView

IRecyclerView is a custom RecyclerView that supports pull-to-refresh, pull-to-loadmore, customize refresh header and loadmore footer, add header views and footer views.
729 stars 146 forks source link

给表格添加间隔线(addItemDecoration)后,顶部和底部间距就会有问题 #38

Closed StudyPlay closed 7 years ago

StudyPlay commented 7 years ago
recyclerView.addItemDecoration(new GridSpacingItemDecoration(2,
                (int) (4 * getResources().getDisplayMetrics().density), true));
        gridLayoutManager = new GridLayoutManager(getContext(), 2);

最顶部和底部的间距和其它的间距不同,

其它代码:

public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {

    private int spanCount;
    private int spacing;
    private boolean includeEdge;

    public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) {
        this.spanCount = spanCount;
        this.spacing = spacing;
        this.includeEdge = includeEdge;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        int position = parent.getChildAdapterPosition(view); // item position
        int column = position % spanCount; // item column

        if (includeEdge) {
            outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing)
            outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing)

            if (position < spanCount) { // top edge
                outRect.top = spacing;
            }
            outRect.bottom = spacing; // item bottom
            LogUtil.e("Grid", "top:" + outRect.top + ", position:" + position);
        } else {
            outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing)
            outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f /    spanCount) * spacing)
            if (position >= spanCount) {
                outRect.top = spacing; // item top
            }
        }
    }
}
Aspsine commented 7 years ago
--------------------------------
position:0 | refreshHeaderView
--------------------------------
position:1 | headerViews
--------------------------------
position:2 | your itemView 0
--------------------------------
position:3 | your itemView 1
--------------------------------
position:4 | your itemView 2
--------------------------------
position:5 | footerViews
--------------------------------
position:6 | loadMoreFooterView
--------------------------------

如果你的 Adapter getItemCount() 返回 3,说明列表中需要展示 3 个 view。在IRecyclerView中,会占用 最上面的2个view和最下面的2个view。

如果你给 RecyclerView 设置了 ItemDecoration, RecyclerView 会给所有的 子view 设置 ItemDecoration。

所以,你需要修改

public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
    int position = parent.getChildAdapterPosition(view); // item position
    int column = position % spanCount; // item column

    if (includeEdge) {
        outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing)
        outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing)

        if (position < spanCount) { // top edge
            outRect.top = spacing;
        }
        outRect.bottom = spacing; // item bottom
        LogUtil.e("Grid", "top:" + outRect.top + ", position:" + position);
    } else {
        outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing)
        outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f /    spanCount) * spacing)
        if (position >= spanCount) {
            outRect.top = spacing; // item top
        }
    }
}

public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
    int position = parent.getChildAdapterPosition(view); // item position
    RecyclerView.Adapter adapter = parent.getAdapter();
    if (position > 1 && position < adapter.getItemCount() - 2) {
        int column = position % spanCount; // item column
        if (includeEdge) {
            outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing)
            outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing)

            if (position < spanCount) { // top edge
                outRect.top = spacing;
            }
            outRect.bottom = spacing; // item bottom
            LogUtil.e("Grid", "top:" + outRect.top + ", position:" + position);
        } else {
            outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing)
            outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f /    spanCount) * spacing)
            if (position >= spanCount) {
                outRect.top = spacing; // item top
            }
        }
    }
}
Aspsine commented 7 years ago

4