Recyclerview分隔符自定义

2021-10-13  本文已影响0人  100个大西瓜

在列表中需要添加空白的分隔符,原来是直接在item_view中使用了layout_marginBottom来实现,后来发现有问题,就是最后一项也出现了分隔符,看起来怪怪的。
于是搜索了一番,发现可以自定义RecyclerView.ItemDecoration来实现,例如参考了这个

RecyclerView自定义分割线
但经过验证,发现最后一项还是带了自定义的分隔符,

        /**
         * Retrieve any offsets for the given item. Each field of <code>outRect</code> specifies
         * the number of pixels that the item view should be inset by, similar to padding or margin.
         * The default implementation sets the bounds of outRect to 0 and returns.
         *
         * <p>
         * If this ItemDecoration does not affect the positioning of item views, it should set
         * all four fields of <code>outRect</code> (left, top, right, bottom) to zero
         * before returning.
         *
         * <p>
         * If you need to access Adapter for additional data, you can call
         * {@link RecyclerView#getChildAdapterPosition(View)} to get the adapter position of the
         * View.
         *
         * @param outRect Rect to receive the output.
         * @param view    The child view to decorate
         * @param parent  RecyclerView this ItemDecoration is decorating
         * @param state   The current state of RecyclerView.
         */
        public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
                @NonNull RecyclerView parent, @NonNull State state) {
            getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(),
                    parent);
        }

这个方法可以来定义分隔符的大小,
一顿操作之后,实现了如下:

package com.your.pkg;


import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

/**
 * 最后一项不带分割线
 * copy from {@link DividerItemDecoration}
 */
public class CustomDecoration extends DividerItemDecoration {
    public static final String TAG = "CustomDecoration";

    private int mOrientation2;
    private boolean mIsLinearLayoutManager = false;
    private RecyclerView.LayoutManager mLayoutManager;

    public CustomDecoration(Context context, int orientation) {
        super(context, orientation);
        this.mOrientation2 = orientation;
    }

    /**
     * Sets the orientation for this divider. This should be called if
     * {@link RecyclerView.LayoutManager} changes orientation.
     *
     * @param orientation {@link #HORIZONTAL} or {@link #VERTICAL}
     */
    public void setOrientation(int orientation) {
        super.setOrientation(orientation);
        this.mOrientation2 = orientation;
    }

    /**
     * only support {@link androidx.recyclerview.widget.LinearLayoutManager}
     * 其他的执行默认规则
     */

    @Override
    public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent,
                               @NonNull RecyclerView.State state) {
        Drawable mDivider = getDrawable();
        if (mDivider == null) {
            outRect.set(0, 0, 0, 0);
            return;
        }

        if (mOrientation2 == VERTICAL) {
            //2021/10/12 仅支持LinearLayoutManager
            final int itemPosition = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewLayoutPosition();
            final RecyclerView.Adapter adapter = parent.getAdapter();
            final RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
            int childCount = 0;

            if (mLayoutManager != layoutManager) {
                mLayoutManager = layoutManager;
                mIsLinearLayoutManager = (mLayoutManager instanceof LinearLayoutManager);
            }
            if (mIsLinearLayoutManager && adapter != null) {
                childCount = adapter.getItemCount();

            }
            //最后一项
            final boolean isLastRow = childCount > 0 && (itemPosition == childCount - 1);
            if (isLastRow) {
                outRect.set(0, 0, 0, 0);
            } else {
                outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
            }

        } else {
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
        }
    }

}

最小程度地修改源码,避免引进新的bug.
基本可以满足自己的需要了,但是不完美的,因为这次修改只支持LinearLayoutManager 以及 垂直滑动的,其他的暂不支持

上一篇下一篇

猜你喜欢

热点阅读