竖向
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));
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;
}
}