RecycleView-自定义分割线-ItemDecoration

本文介绍了在Android中如何使用RecyclerView.ItemDecoration来自定义分割线,包括如何实现纵向和横向分割线,以及getItemOffsets和onDrawOver方法的作用。通过实例展示了如何根据需求设置分割线的分布,强调了itemDecoration在布局定制中的灵活性。
摘要由CSDN通过智能技术生成

最近一段时间牙疼的不行,只能喝粥。鼓起勇气看了次牙医,发现2颗牙齿已经被虫子蛀到了神经,要把牙神经拔掉。现在想想真是后悔啊啊!!!各位程序员在写代码的同时,千万不要忘了好好呵护自己的牙齿!!千万!!

今天接到一个需求,大体就是实现一个网格布局,布局里元素有的左边没分割线,有的右边没分割线,有的分割线加粗……等等,总之分割线的分布完全没有规律,必须需要自定义来实现。琢磨了一下,发现RecycleView自带的itemDecoration可以完美的解决这个问题。

RecyclerView.ItemDecoration

利用RecycleView自带的这个类,可以完美的自定义各种分割线。只有你想不到的,没有itemDecoration做不到的!

这个类的核心方法有三个:

  • onDraw(Canvas c, RecyclerView parent, State state)
  • onDrawOver(Canvas c, RecyclerView parent, State state)
  • getItemOffsets(Rect outRect, View view, RecyclerView parent, State state)

首先看一下onDraw(Canvas c, RecyclerView parent, State state)

public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state)
{
    //画水平分割线
    drawHorizontal(c, parent);
    //画垂直分割线
    drawVertical(c, parent);
}

onDraw这个方法中,主要来为每个子View画分割线,具体的做法可以计算出每个子View的(left,top,right,bottom) , 然后在这个区域内画上分割线。如果想做成listView的效果可以只画水平的分割线,如果想做成网格的布局可以同时实现纵向和横向的分割线。

来举个例子,实现一下纵向的分割线:

public void drawVertical(Canvas c, RecyclerView parent)
{
    //首先来获取子item的数量,来决定你画的分割线的数量
    final int childCount = parent.getChildCount();
    //然后做一个for循环来为你的子Item画上分割线
    for (int i = 0; i < childCount; i++)
    {
        final View child = parent.getChildAt(i);
        //拿到子View的布局属性
        final RecyclerView.LayoutParams params =       (RecyclerView.LayoutParams) child
                .getLayoutParams();
        //这里开始来设置分割线的区域
        final int top = child.getTop() - params.topMargin;
        final int bottom = child.getBottom() + params.bottomMargin;
        //我这里默认从item的右侧开始画,所以分割线的left区域我取了子View的Right + margin
        final int left = child.getRight() + params.rightMargin;
        //这里注意了,小伙伴们!mDivider.getIntrinsicWidth() 代表了分割线的宽度,你可以自己设比如50。也可以直接取mDivider的宽度。 mDivider是一个我已经画好的一个分割线drawble,很简单。因为通过drawble可以定义一下分割线的颜色,透明度等。十分的灵活
        final int right = left + mDivider.getIntrinsicWidth();
        if(i != 1){
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }
}

好了,以上就是纵向分割线的实现,很简单吧。横向分割线的实现也是同理。如果想做成一个万能的分割线,可以在构造中传入参数来决定是需要横向的还是纵向的还是网格的。

getItemOffsets

这个函数看了下网上说的,感觉都说的比较复杂。我这里就不做深入的分析了,简洁明了的帮助大家来理解下。

这个函数,3个参数:

  • Rect outRect
  • int itemPosition
  • RecyclerView parent

首先第一个参数,也是最重要的一个参数。先看以下4副图,分别是outRect不同参数下的表现。

outRect不同参数体现

从图中可以看出,outRect(left,top,right,bottom) 实际上可以理解为对子View做了一次的padding,他代表分割线可以显示的区域。由于itemDecoration的分层是在parent层之上,子View层之下,即分层由下到上依次是paret < itemDecoration < 子View 。 而 getItemOffsets函数是来操作顶层的子View可以给itemDecoration显示的区域。
举个例子:
如图3 (50,50,0,50)代表了子View左上右分别可以给itemDecoration 50像素来展示,而右边即使你在onDraw中画了,也会被子View给盖住而展示不出来。

我在这里做了个有趣的实验,即我把子View的背景设成了透明,这个方法无论如何设置,都失效了。这正验证了我上面的理论,即子View的背景透明后,无论你怎么设置itemDecoration的显示区域,最上层的子View都无法将处于下层的itemDecoration给遮住。 有兴趣的朋友可以试一试。

最后来讲一讲onDrawOver()

onDrawOver

顾名思义这是绘制在最上层的画布,甚至比子View所绘制的画布还要顶层。

decoration 的 onDraw,child view 的 onDraw,decoration 的 onDrawOver,这三者是依次发生的。而由于 onDrawOver 是绘制在最上层的,所以它的绘制位置并不受限制(当然,decoration 的 onDraw 绘制范围也不受限制,只不过不可见),所以利用 onDrawOver 可以做很多事情,例如为 RecyclerView 整体顶部绘制一个蒙层,或者为特定的 item view 绘制蒙层。

好了,以上就是今天要分享的内容。总结一下,itemDecoration可以为你的RecycleView定制各种各样的分割线。当然这是最基础的用法,例如用最后提到的onDrawOver来实现蒙层等

最近一直在研究VPN,有时间要好好总结一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值