RecyclerView 的ItemDecoration 间隔设置

RecyclerView 的item间隔设置

线性布局

竖向

public class VerticalItemDecoration extends RecyclerView.ItemDecoration {
    private int space;//定义2个Item之间的距离
    private boolean setTopAndBottom = false;

    public VerticalItemDecoration(int space, Context mContext) {
        this.space = dip2px(space, mContext);
    }

    public VerticalItemDecoration(int space, Context mContext, boolean setTopAndBottom) {
        this.space = dip2px(space, mContext);
        this.setTopAndBottom = setTopAndBottom;
    }

    @Override
    public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        int position = parent.getChildAdapterPosition(view);
        int totalCount = parent.getAdapter().getItemCount();
        if (position == 0) {//第一个
            outRect.top = 0;
            if (setTopAndBottom) {
                outRect.top = space;
            }
            outRect.bottom = space / 2;
        } else if (position == totalCount - 1) {//最后一个
            outRect.top = space / 2;
            outRect.bottom = 0;
            if (setTopAndBottom) {
                outRect.bottom = space;
            }
        } else {//中间其它的
            outRect.top = space / 2;
            outRect.bottom = space / 2;
        }
    }

    public int dip2px(float dpValue, Context context) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}

使用方式

//true 代表 第一个item 加上间距和最后一个item 下边间距
recyclerview.addItemDecoration(new VerticalItemDecoration(10, this, true));

横向

public class HorizontalItemDecoration extends RecyclerView.ItemDecoration {
    private int space;//定义2个Item之间的距离
    private boolean setLeftAndRight = false;

    public HorizontalItemDecoration(int space, Context mContext) {
        this.space = dip2px(space, mContext);
    }

    public HorizontalItemDecoration(int space, Context mContext, boolean setLeftAndRight) {
        this.space = dip2px(space, mContext);
        this.setLeftAndRight = setLeftAndRight;
    }

    @Override
    public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        int position = parent.getChildAdapterPosition(view);
        int totalCount = parent.getAdapter().getItemCount();
        if (position == 0) {//第一个
            outRect.left = 0;
            if (setLeftAndRight) {
                outRect.left = space;
            }
            outRect.right = space / 2;
        } else if (position == totalCount - 1) {//最后一个
            outRect.left = space / 2;
            outRect.right = 0;
            if (setLeftAndRight) {
                outRect.right = space;
            }
        } else {//中间其它的
            outRect.left = space / 2;
            outRect.right = space / 2;
        }
    }

    public int dip2px(float dpValue, Context context) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}

使用方式

//true 代表 第一个item 加左边间距和最后一个item 右边间距
recyclerview.addItemDecoration(new HorizontalItemDecoration(15, mContext, true));

网格布局

public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {

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

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

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        int position = parent.getChildAdapterPosition(view);
        int column = position % spanCount;
        if (includeEdge) {
            outRect.left = spacing - column * spacing / spanCount;
            outRect.right = (column + 1) * spacing / spanCount;
            if (position < spanCount) {
                outRect.top = spacing;
            }
            outRect.bottom = spacing;
        } else {
            outRect.left = column * spacing / spanCount;
            outRect.right = spacing - (column + 1) * spacing / spanCount;
            if (position < spanCount) {
                outRect.top = spacing;
            }
            outRect.bottom = spacing;
        }
    }

    public int dip2px(float dpValue, Context context) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}

使用方式

//true 代表 上下左右四周,都加上间距
recyclerview.addItemDecoration(new GridSpacingItemDecoration(mContext, 3, 10, true));

瀑布流

鉴于瀑布流见缝插针的特性,左右间距,无法做到网格布局那样一步到位;所以还需要在recyclerview 布局中设置左右 padding 间距,这个间距是你设置的总间距的一半

public class StaggeredDividerItemDecoration extends RecyclerView.ItemDecoration {
    private Context context;
    private int spacing;
    private int spanCount;

    public StaggeredDividerItemDecoration(Context context, int spacing, int spanCount) {
        this.context = context;
        this.spacing = dip2px(spacing, context);
        this.spanCount = spanCount;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        int position = parent.getChildAdapterPosition(view);
        StaggeredGridLayoutManager.LayoutParams params = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
        // 获取item在span中的下标
        int spanIndex = params.getSpanIndex();

        if (position < spanCount) {
            outRect.top = spacing;
        }
        // 中间间隔
        //放弃之前的方法。这里设置让左右一样列表左右切换导致中间距离出现问题
        outRect.left = spacing / 2;
        outRect.right = spacing / 2;

        // 下方间隔
        outRect.bottom = spacing;
    }

    public int dip2px(float dpValue, Context context) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}

使用方式

recyclerview.addItemDecoration(new StaggeredDividerItemDecoration(mContext, 5,2));

一个自定义限制最大高度recyclerview

public class MaxHeightRecyclerView extends RecyclerView {
    private int mMaxHeight;

    public MaxHeightRecyclerView(@NonNull Context context) {
        super(context);
    }

    public MaxHeightRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initialize(context, attrs);
    }

    public MaxHeightRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initialize(context, attrs);
    }

    private void initialize(Context context, AttributeSet attrs) {
        TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.MaxHeightRecyclerView);
        mMaxHeight = arr.getLayoutDimension(R.styleable.MaxHeightRecyclerView_maxHeight, mMaxHeight);
        arr.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mMaxHeight > 0) {
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxHeight, MeasureSpec.AT_MOST);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public int getmMaxHeight() {
        return mMaxHeight;
    }

    public void setmMaxHeight(int mMaxHeight) {
        this.mMaxHeight = mMaxHeight;
    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值