Recyclerview中实现分割效果需要用到ItemDecoration,它是一个抽象类,用来绘制分割效果,使用的时候需要重写这个方法,下面先看一下他的源码:
public static abstract class ItemDecoration {
@param c Canvas to draw into
@param parent RecyclerView this ItemDecoration is drawing into
@param state The current state of RecyclerView
public void onDraw(Canvas c, RecyclerView parent, State state) {
onDraw(c, paren);
@param c Canvas to draw into
@param parent RecyclerView this ItemDecoration is drawing into
@param state The current state of RecyclerView.
public void onDrawOver(Canvas c, RecyclerView parent, State state) {
onDrawOver(c, parent);
}
@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(Rect outRect, View view, RecyclerView parent, State state) {
getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(),
parent);
}
}
去掉已经不建议使用的,还有三个主要个方法
onDraw(Canvas c, RecyclerView parent, State state)
用来绘制分割线,在ItemView绘制之前,如果分割线越界,会显示在ItemView上层
onDrawOver(Canvas c, RecyclerView parent, State state)
用来绘制分割线,在ItemView绘制之后。如果分割线越界,会显示在ItemView下层
getItemOffsets
来指定itemview对应的分割线位置和大小。outRect存放了decoration的四个角坐标。通过outRect.set(l, t, r, b)
来设置。它的原理实际上是对ItemView来设置Padding,从而为decoration留出对应的空间,单位是px
了解了这些之后,可以实现一个很简单的分割效果了,这里针对一个Vertical方向的Recyclerview绘制黑色分割。
首先定义分割线,使用了ShapeDrawable,定义一个5px高的黑色图形(divider.xml):
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<size android:height="5px"></size>
<solid android:color="@color/colorBlack"></solid>
</shape>
然后实现ItemDecoration,绘制分割线:
private class BlackDecoration extends RecyclerView.ItemDecoration{
private Drawable mDivider;
public BlackDecoration(Context context) {
//获取我们定义的Drawable
mDivider = context.getDrawable(R.drawable.divider);
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
//指定Drawable的坐标,这里是竖直方向,所以每个分割线的左右都是一样的,获取Recyclerview的padding就可以了,与ItemView的尺寸相同
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
//分割线是一个一个单独绘制的,需要分别对每个Item的分割线获取到top和Bottom坐标
for(int i = 0; i<parent.getChildCount(); i++){
View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
//top的位置应该是itemView的底部,另外还要加上itemView的MarginBottom,和竖直方向的位移。就是itemView 的下边界
final int top = child.getBottom() + params.bottomMargin +
Math.round(ViewCompat.getTranslationY(child));
//top加divider的高度就是bottom了
final int bottom = top + mDivider.getIntrinsicHeight();
//设置divider边界并进行绘制
mDivider.setBounds(left,top,right,bottom);
mDivider.draw(c);
}
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
//设置Itemview的padding,为divider留出位置。
outRect.set(0,0,0,mDivider.getIntrinsicHeight());
}
}
最后就是对Recyclerview设置分割了,mRecyclerView.setAdapter(new RecycleAdapter());
,运行之后就可以看到效果了,每个item之间会有黑色的分割线。
关于分割线的详细介绍可以参考鸿扬大神的博客Android RecyclerView 使用完全解析 体验艺术般的控件,可以通过指定theme的<item name="android:listDivider">@drawable/divider_bg</item>
来实现不同的分割效果
网友评论