理解RecyclerView的RecyclerView.ItemDecoration(一)

来源:互联网 发布:网络买彩票合法吗 编辑:程序博客网 时间:2024/06/10 05:16

最近在看到别人使用RecyclerView实现了类似事件线的东东,老大也叫我搞了一个,先guyhub上搜了一个,看下图:
这里写图片描述

上图是个妹子写的,文章的最后我会你他的地址,毕竟全球最大同性交友网站上有些妹子还比较不错的。我没有down她的代码,而是看了一个说明,是用RecyclerView写的,但是使用了ItemDecoration作为修饰,才变成了这样好看的样子。这个ItemDecoration类用的很频繁,因为现在换成了RecyclerView,没有以前ListView那样有divider,所以需要一些分割线还是需要它的帮助。今天暴脾气上来了,以前没怎么好好研究它,今天有时间就好好撸一番。

ItemDecoration是RecyclerView内部的一个抽象类,但是所有的方法都有默认实现,我们一个一个方法来研究研究:

public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {}

看名字,是获取每个Item的偏移量。说的蛮轻巧的,到底什么意思呢? 我也不知道,看文档也模棱两可的,好吧,它不是要设置outRect吗,我们就设置一个outRect来测试一下我们的getItemOffsets,我们先来实现一下ItemDecoration:

public class CustomItemDecoration extends RecyclerView.ItemDecoration {    //只传入Rect    private Rect mRect;    public CustomItemDecoration(Rect mRect) {        this.mRect = mRect;    }    @Override    public void getItemOffsets(Rect outRect,                               View view,                               RecyclerView parent,                               RecyclerView.State state) {        if(null != mRect) {            outRect.set(mRect);        }    }    //外部更新我们mRect    public void setRect(Rect mRect) {        this.mRect = mRect;    }}

MainActivity中:

        //step1        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));        //step2        mRecyclerView.setAdapter(new CustomAdapter(Data.getDataSource()));        //step3 set ItemDecoration        mRect = new Rect();        mCustomItemDecoration = new CustomItemDecoration(mRect);        mRecyclerView.addItemDecoration(mCustomItemDecoration);

MainActivity中另外的实现为:
这里写图片描述

下面的四个seekbar分别控制Rect的left,top, right 和bottom的值大小,其余的都不变:

    public void changeRect() {        mRect.set(mLeft.getProgress(),                mTop.getProgress(),                mRight.getProgress(),                mBottom.getProgress());        mCustomItemDecoration.setRect(mRect);        mRecyclerView.addItemDecoration(mCustomItemDecoration);    }

那我们就看移动一下seekbar,动态观察一下我们ItemDecoration发生的变化:
这里写图片描述

看到这里,基本上也就明白了这里的Rect到底是什么意思了,Rect中有四个属性分别是left,top,right和bottom,那么这四个属性现在就相当于每一个item的padding值了,我书读的比较多,不会骗你,不是很明白么? 那么你就看看下图:
这里写图片描述

从图中可以看出,Rect的left和right值越大,那么就相当于item的paddingLeft和paddingRight值越大,那么就意味着留给Item的宽度就越小;而Rect.top和bottom越大,就表明Item的paddingTop和paddingBottom越大,那么我们的Item的高度就越高,这里的Rect就相当于我们的item的padding了,但是它和真实的padding还是有区别的,你可以看上面的gif动图,我们会发现它上面的背景也是变化的,但是变化的仅仅是宽度,而背景的高度是不变的(当然了这是针对LinearLayout.VERTICAL而言的,对于Linearlayout.HORIZONTAL的情况当然是相反了),它改变了item的真实宽度,也改变了item的真实高度,但是对于RecyclerView的draw方法而言,item的可视高度是不变的,因为adapter中inflate的View没有改变。所以我们就想象它起到padding的作用,但是不是真的padding那样。

那么这个方法到底有什么用呢??
知道了这个方法我们就可以去画我们想要的divider了,先来画个简单的:
这里写图片描述

我们先来分析一下这个Item界面,想要画出我们的divider,当然你也可以在item的layout中添加一个红色的View,这个比较low啊,来看看使用我们的ItemDecoration怎么做?还是先看图吧:
这里写图片描述
这次我们需要将我们的Rect设置成这样:

outRect.set(0,0,40,0);

那为什么不设置top呢?看上去也是可以实现的啊,嗯,看上去的确是可以的,但是对于第一个来说,它就变成了这个样子:
这里写图片描述

你可以看到上面的黑色框中,也就是我们的第一个item存在paddingTop的情况,当然这种设计我倒也是经历过,当初真的没想过要这么做过。

好了,第一个方法我估计我已经扯清楚了,明天的话有时间的,就把以下两个方法扯一下,争取真正去理解我们的ItemDecoration吧。

@Override=public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {        super.onDrawOver(c, parent, state);    } @Override    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {        super.onDraw(c,parent,state);    }

好了,就写到这里吧。

阅读全文
1 0
原创粉丝点击