RecyclerView --- 分割线

【记录】记录点滴

【需求】简单使用分割线与自定义分割线

1. 利用DividerItemDecoration, 简单实现分割线

2. 基于RecyclerView.ItemDecoration,自定义分割线

简单使用RecyclerView中,最后实现了个嵌套的界面,一个Linear List嵌套一个Grid。先上最终实现的效果图

其中Grid中的自定义分割线比较细,所以图大些。

1. 利用DividerItemDecoration

在外层的 List 中实现渐变色的布局

先定义个渐变色的shape,作为分割线

<!-- 渐变色的分割线 -->
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient
        android:startColor="@android:color/holo_red_light"
        android:endColor="@android:color/holo_green_light"/>
    <size
        android:height="1dp"/>
</shape>

然后在代码中创建DividerItemDecoration实例,并添加到RecyclerView中,如下

...
DividerItemDecoration decoration = new DividerItemDecoration(MultiTypeRecyclerActivity.this, DividerItemDecoration.VERTICAL);
decoration.setDrawable(ContextCompat.getDrawable(this,R.drawable.shape_item_decoration));
recyclerview.addItemDecoration(decoration);
...

到这里,就实现了简单的分割线。

2. 基于RecyclerView.ItemDecoration

DividerItemDecoration实际也是基于RecyclerView.ItemDecoration实现的,从源码中可以看出,它只支持画“水平”或“竖直”的分割线。需要关注的几个方法是:

//画在item的下层,如果和item有重叠部分,会被item的重叠部分掩盖
public void onDraw()

//画在item的上层,如果和item有重叠部分,会覆盖item的重叠部分,并展示
public void onDrawOver()

//item上下左右处的间隔距离
//但不能说这里是设置分割线尺寸的地方
public void getItemOffsets()

先看看这个丑样子,每个item上下左右不仅实现了不同颜色的分割线,还在item的上侧画了条粗的黑色分割线,并在下侧有一条细的黑色分割线(这条分割线实际是画了条粗的,但是被item遮盖了一部分,只展示出一点边缘)。

 

一步步实现:

1)仔细看,item中间还有灰色,这是因为设置了灰色的背景,并且通过getItemOffsets设置了item间的间距,如下

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
    super.getItemOffsets(outRect, view, parent, state);
    //获得View在Recycler中的位置
    int position = parent.getChildAdapterPosition(view);
    if(position < 3){
        //前三个上下左右都是10px间隔
        outRect.set(10, 10, 10, 10);
    } else {
        //其他左侧没有间隔,上下右是10px的间隔,左侧没有间隔
        outRect.set(0, 10, 10, 10);
    }
}

2)接下来就是画分割线

                @Override
                public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
                    //画在下层
                    super.onDraw(c, parent, state);
                    Paint pleft = new Paint();
                    Paint pright = new Paint();
                    Paint ptop = new Paint();
                    Paint pbottom = new Paint();
                    pleft.setColor(Color.BLUE);
                    pright.setColor(Color.GREEN);
                    ptop.setColor(Color.YELLOW);
                    pbottom.setColor(Color.RED);
                    Rect rleft = new Rect();
                    Rect rright = new Rect();
                    Rect rtop = new Rect();
                    Rect rbottom = new Rect();

                    Paint pBack = new Paint();
                    pBack.setColor(Color.BLACK);
                    for(int i = 0; i < parent.getChildCount(); i++){
                        View v = parent.getChildAt(i);
                        rleft.set(v.getLeft() - 5, v.getTop(), v.getLeft(), v.getBottom());
                        rright.set(v.getRight(), v.getTop(), v.getRight() + 5, v.getBottom());
                        rtop.set(v.getLeft(), v.getTop() - 5, v.getRight(), v.getTop());
                        rbottom.set(v.getLeft(), v.getBottom(), v.getRight(), v.getBottom() + 10);
                        //上下左右的四条分割线
                        c.drawRect(rleft, pleft);
                        c.drawRect(rright, pright);
                        c.drawRect(rtop, ptop);
                        c.drawRect(rbottom, pbottom);
                        //在每个item的下侧画,一条25高的黑色分割线
                        //但是因为画在下层,被item遮盖了一部分,所以就变成细细的一条
                        c.drawRect(new Rect(v.getLeft(), v.getBottom() - 20, v.getRight(), v.getBottom() + 5), pBack);
                    }
                }

                @Override
                public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
                    //在每个item的上侧画一条黑色分割线,因为画在上层,所以遮盖了item的一部分,并全部展示了出来
                    super.onDrawOver(c, parent, state);
                    Paint p = new Paint();
                    p.setColor(Color.BLACK);
                    for(int i = 0; i < parent.getChildCount(); i++){
                        View v = parent.getChildAt(i);
                        c.drawRect(new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getTop() + 20), p);
                    }
                }

PS:如果考虑下padding时的效果,要在onDraw和onDrawOver中加入代码段

...
//如果RecyclerView的clipToPadding设置了true,则裁剪Canvas,不在padding区域内绘制内容
if (parent.getClipToPadding()) {
    int canvasLeft = parent.getPaddingLeft();
    int canvasRight = parent.getWidth() - parent.getPaddingRight();
    int canvasTop = parent.getPaddingTop();
    int canvasBottom = parent.getHeight() - parent.getPaddingBottom();
    canvas.clipRect(canvasLeft, canvasTop, canvasRight, canvasBottom);
}
...

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值