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;
    }
}

你可能感兴趣的:(android学习笔记,Android,recyclerview)