RecyclerView的基本使用与进阶(二)

上一篇讲了RecyclerView最基本的使用,那点东西是不足以用到实际开发中的,一般在实际开发的时候,我们都会为每个item添加一条分割线,那么这篇文章就讲讲添加分割线的几种方式以及如何定制分割线,来画出酷炫的分割线

利用背景颜色来绘制简单分割线:

比如我们将RecyclerView的背景颜色设置为黑色,然后在adapter中的onBindViewHodler给item设置margin就能达到分割线的效果:

RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) holder.itemView.getLayoutParams();
        params.topMargin = 2;
        holder.itemView.setLayoutParams(params);

或者利用ItemDicoration实现分割线,但其实也是利用背景颜色:
新建类继承自ItemDicoration,覆写getItemOffsets()

public class MyDividerItemDecoration extends RecyclerView.ItemDecoration {
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        if (parent.getChildAdapterPosition(view) != 0) {
            outRect.top = 1;
        }
    }
}

先判断是否是第一个item,如果是则不设置margin,然后我们在activity添加上

rv.addItemDecoration(new MyDividerItemDecoration());

当然,还有一个更简单的方式,官方为我们提供了添加分割线的方法,只需要在activity中添加如下代码:

rv.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL));

效果都是一样的,不过官方为我们提供的分割线可以更优雅的自定义分割线的样式
在drawable中新建一个xml
类型设置为shape:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <gradient
        android:centerColor="@color/colorPrimary"
        android:endColor="@color/colorPrimary"
        android:startColor="@color/colorPrimary"
        android:type="linear"/>
    <size android:height="2dp"/>
</shape>

参数名称就不用解释了,看名字就知道啥意思,然后在当前APP引用的style中添加如下属性

<item name="android:listDivider">@drawable/divider</item>

然后就大功告成了,效果图不贴了,有兴趣自己去试试吧
既然已经引出了ItemDecoration,那么就要好好介绍一下该类
官方的介绍是:An ItemDecoration allows the application to add a special drawing and layout offset to specific item views from the adapter’s data set. This can be useful for drawing dividers between items, highlights, visual grouping boundaries and more.
简单翻译一下,允许adapter设置特定的视图或偏移量。就是说可以自定义偏移量甚至是视图
那么我们来给每个item左边画个圆
既然要在画布上画某个东西,那么就一定需要画笔

private Paint mPaint;

然后覆写onDraw方法,既然我们要给每一个item左边绘制一个圆,那么就要获取到每一个item

@Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
        int childCount = parent.getChildCount();
        for (int i = 0; i <childCount; i++) {
            View view = parent.getChildAt(i);
            int index = parent.getChildAdapterPosition(view);
        }
    }

这样就获取到了每一个item,画圆就需要用canvas.drawCircle,其中有四个参数,分别是:
float cx:圆心的x轴坐标
float cy:圆心的y轴坐标
float radius: 圆的半径
Paint paint:这个就不解释了
那么来看看圆心的x轴坐标怎么计算:
首先,我们是将圆绘制在左边,那么我们就需要获取到左边的大小
即:
float left = view.getLeft()
圆心的x轴左边就是

float cx = left / 2;

再来计算y轴坐标:
y轴坐标计算相比之下就比较复杂一点,y轴圆心必定是在高的中间,所以我们需要获取到top和bottom

float top = view.getTop();
float bottom = view.getBottom();
float cy = top + (bottom - top) / 2;

来看看效果

附上完整代码:

public class MyDividerItemDecoration extends RecyclerView.ItemDecoration {
    private Paint mPaint;
    private float mOffsetLeft;//距离左边的偏移量
    private float mOffsetTop;//距离顶端的偏移量
    private float radius;//圆的半径

public MyDividerItemDecoration(Context context) {
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setColor(Color.BLACK);
    mOffsetLeft = context.getResources().getDimension(R.dimen.offSetLeft);
    radius = context.getResources().getDimension(R.dimen.radius);
}

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
    super.getItemOffsets(outRect, view, parent, state);
    if (parent.getChildAdapterPosition(view) != 0) {
        mOffsetTop = 1;
        outRect.top = 1;
    }
    outRect.left = (int) mOffsetLeft;
}

@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
    super.onDraw(c, parent, state);
    int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++) {
        View view = parent.getChildAt(i);
        int index = parent.getChildAdapterPosition(view);
        float left = view.getLeft();
        float bottom = view.getBottom();
        float top = view.getTop();
        if (i == 0) {
            top = mOffsetTop;
        }
        float cx = left / 2;
        float cy = top + (bottom - top) / 2;
        c.drawCircle(cx,cy,radius,mPaint);
    }
}

以上就是分割线的绘制及简单的itemDecoration的使用,如有错误,还请指出

坚持原创技术分享,您的支持将鼓励我继续创作!