RecyclerView ItemDecoration 自定义高度和颜色
Posted 威威dett
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RecyclerView ItemDecoration 自定义高度和颜色相关的知识,希望对你有一定的参考价值。
自定义高度和颜色RecyclerView ItemDecoration
自定义RecyclerView ItemDecoration,针对RecyclerView的横向和竖向的分割线,具体特点如下
- 支持像ListView一样可以使用颜色作为分隔线(也支持drawable)
- 支持自定义分割线的高度
- 支持控制是否显示最后一条分割线
下面贴上完整代码供参考
/**
* recycler view 横竖方向使用的divider
*
* @author wangjian
*/
public class LinearDividerItemDecoration extends RecyclerView.ItemDecoration
public static final int HORIZONTAL = 0;
public static final int VERTICAL = 1;
private static final String TAG = "DividerItem";
private static final int[] ATTRS = new int[]android.R.attr.listDivider;
private Context mContext;
private Drawable mDivider;
private int mOrientation;
private int mDividerHeight;
private final Rect mBounds = new Rect();
private boolean showLastDivider;
public LinearDividerItemDecoration(Context context, int orientation)
this.mContext = context;
TypedArray a = context.obtainStyledAttributes(ATTRS);
this.mDivider = a.getDrawable(0);
if (this.mDivider == null)
Log.w("DividerItem", "@android:attr/listDivider was not set in the theme used for this LinearDividerItemDecoration. Please set that attribute all call setDrawable()");
a.recycle();
this.setOrientation(orientation);
/**
* 设置divider方向
*
* @param orientation 方向
*/
public void setOrientation(int orientation)
if (orientation != HORIZONTAL && orientation != VERTICAL)
throw new IllegalArgumentException("Invalid orientation. It should be either HORIZONTAL or VERTICAL");
else
this.mOrientation = orientation;
/**
* 是否显示最后一条分割线
*/
public void setShowLastDivider(boolean showLastDivider)
this.showLastDivider = showLastDivider;
/**
* 设置分割线drawable
*
* @param drawable drawable
*/
public void setDrawable(@NonNull Drawable drawable)
this.mDivider = drawable;
this.mDividerHeight = mDivider.getIntrinsicHeight();
/**
* 设置分割线drawable
*
* @param dividerColor 分割线颜色
* @param dividerHeight 分割线高度,单位dp
*/
public void setDrawable(@ColorInt int dividerColor, int dividerHeight)
this.mDivider = new ColorDrawable(dividerColor);
this.mDividerHeight = DisplayUtils.dip2px(mContext, dividerHeight);
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state)
if (parent.getLayoutManager() != null && this.mDivider != null)
if (this.mOrientation == VERTICAL)
this.drawVertical(c, parent);
else
this.drawHorizontal(c, parent);
private void drawVertical(Canvas canvas, RecyclerView parent)
canvas.save();
int left;
int right;
if (parent.getClipToPadding())
left = parent.getPaddingLeft();
right = parent.getWidth() - parent.getPaddingRight();
canvas.clipRect(left, parent.getPaddingTop(), right, parent.getHeight() - parent.getPaddingBottom());
else
left = 0;
right = parent.getWidth();
int childCount = parent.getChildCount();
childCount = showLastDivider ? childCount : childCount - 1;
for (int i = 0; i < childCount; ++i)
View child = parent.getChildAt(i);
parent.getDecoratedBoundsWithMargins(child, this.mBounds);
int bottom = this.mBounds.bottom + Math.round(child.getTranslationY());
int top = bottom - this.mDividerHeight;
this.mDivider.setBounds(left, top, right, bottom);
this.mDivider.draw(canvas);
canvas.restore();
private void drawHorizontal(Canvas canvas, RecyclerView parent)
canvas.save();
int top;
int bottom;
if (parent.getClipToPadding())
top = parent.getPaddingTop();
bottom = parent.getHeight() - parent.getPaddingBottom();
canvas.clipRect(parent.getPaddingLeft(), top, parent.getWidth() - parent.getPaddingRight(), bottom);
else
top = 0;
bottom = parent.getHeight();
int childCount = parent.getChildCount();
childCount = showLastDivider ? childCount : childCount - 1;
for (int i = 0; i < childCount; ++i)
View child = parent.getChildAt(i);
parent.getLayoutManager().getDecoratedBoundsWithMargins(child, this.mBounds);
int right = this.mBounds.right + Math.round(child.getTranslationX());
int left = right - this.mDividerHeight;
this.mDivider.setBounds(left, top, right, bottom);
this.mDivider.draw(canvas);
canvas.restore();
//由于Divider也有宽高,每一个Item需要向下或者向右偏移,给divider留出绘制空间
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state)
if (mDivider == null)
outRect.set(0, 0, 0, 0);
return;
if (mOrientation == VERTICAL)
//parent.getChildCount() 不能拿到item的总数
//https://stackoverflow.com/questions/29666598/android-recyclerview-finding-out-first
// -and-last-view-on-itemdecoration
int lastPosition = state.getItemCount() - 1;
int position = parent.getChildAdapterPosition(view);
if (position == lastPosition)
if (showLastDivider)
// item view 距离下面的view间距是divider的高度
outRect.set(0, 0, 0, mDividerHeight);
else
outRect.set(0, 0, 0, 0);
else
outRect.set(0, 0, 0, mDividerHeight);
else
int lastPosition = state.getItemCount() - 1;
int position = parent.getChildAdapterPosition(view);
if (showLastDivider || position < lastPosition)
outRect.set(0, 0, mDividerHeight, 0);
else
outRect.set(0, 0, 0, 0);
工具类中的转换方法
public static int dip2px(Context context, float dipValue)
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
final float scale = displayMetrics.density;
return (int) (dipValue * scale + 0.5f);
使用方法介绍,下面是在fragment中使用参考,具体的使用需要根据自己的界面做相应修改
RecyclerView recyclerView;
// 实例化分割线
LinearDividerItemDecoration divider = new LinearDividerItemDecoration(getActivity(), LinearLayoutManager.VERTICAL);
// 设置分割线的颜色和高度,横向的时候使用方法一样
divider.setDrawable(getResources().getColor(R.color.list_divider), 1);
// 也支持定义的drawable和图片drawable
// divider.setDrawable(AppUtils.getDrawable(getActivity(), R.drawable.recycler_divider_10_dp));
// 添加分割线
recyclerView.addItemDecoration(divider);
下面分享上面自定义的drawable分割线,在drawable目录下创建drawable,recycler_divider_10_dp
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:centerColor="#ff00ff00"
android:endColor="#ff0000ff"
android:startColor="#ffff0000"
android:type="linear" />
<size
android:width="3dp"
android:height="3dp" />
</shape>
以上是关于RecyclerView ItemDecoration 自定义高度和颜色的主要内容,如果未能解决你的问题,请参考以下文章
RecyclerView系列:RecyclerView嵌套RecyclerView(BaseRecyclerViewAdapterHelper实现)