接着上一讲,我们看到我们的Demo可以正常的运行,并且能自动加载网络图片,那么为了后面观察的方便,我们取消这种自动加载的功能,使用两个按钮来代替,分别用来增加一个数据和减少一个数据。截图如下:

进击的RecyclerView入门二(来点小装饰?)-LMLPHP

正在我自认为这样的布局已经很完美的时候,产品经理A走过来指着手机说,“这样的布局太单调,给我改炫酷屌炸天一点!!!”

既然老大这么说了,我也没办法只能照办了。

想到要修改布局我第一个想到的是修改每个Item的布局文件(虽然这里我们没有布局文件,纯java写的),但仔细一想这样改了每一个Item还不是一样。那有没有什么办法可以区别对待这些Item,让不同位置的他们表现的不一样呢?

答案是Yes,RecyclerView有这么一个子ItemDecoration类专门是用来处理这类问题的。

我们先来看一下ItemDecoration的官方介绍:

简单理解就是ItemDecoration可以给指定的Item绘制指定的内容和添加偏移量。其中OnDraw发生在Item绘制前,OnDrawOver发生在Item绘制后。

了解完这些后我们就开始实战吧.

进击的RecyclerView入门二(来点小装饰?)-LMLPHP

要做的很简单我们自定义一个ItemDecoration子类并重写它的如下方法即可:

//用于调整子View的偏移量
public void getItemOffsets (Rect outRect, View view, RecyclerView parent, RecyclerView.State state) //在子View绘制前绘制
onDraw (Canvas c, RecyclerView parent, RecyclerView.State state) //在子View绘制后绘制
onDrawOver (Canvas c, RecyclerView parent, RecyclerView.State state)

我们重写子类如下:

private class MyItemDecoration extends RecyclerView.ItemDecoration{

        Paint paint = new Paint();

        public MyItemDecoration(){
//初始化画笔
paint.setStyle(Paint.Style.STROKE);
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.BLUE);
paint.setStrokeWidth(10);
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { } @Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
//在子View绘制后绘制
//我们布局是每行三个Item,当绘制到中间Item的时候,给他包裹一个相框,虽然我们的相框很挫。。。
for(int i = 0 ; i<parent.getChildCount();i++){
if( (i-1)%3 == 0 ){
View child = parent.getChildAt(i);
RecyclerView.LayoutParams rLP = (RecyclerView.LayoutParams) child.getLayoutParams();
int left = child.getLeft() ;
int top = child.getTop();
int right = child.getRight();
int bottom = child.getBottom() ;
c.drawRect(left,top,right,bottom,paint);
}
}
} @Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
//我们原始的布局所有的Item上下左右都有一个20像素的外边距
//这里我们修改成每行的第一个Item的左边距为0,每行第三个Item的右边距为0.
int position = parent.getChildAdapterPosition(view);
if( (position + 1)%3==0 ){
outRect.set(0,0,-20,0);
}
if(position % 3 == 0){
outRect.set(-20,0,0,0);
}
}
}

最后将这个ItemDecoration追加到RecyclerView上:

final MyItemDecoration myItemDecoration = new MyItemDecoration();
recyclerView.addItemDecoration(myItemDecoration);

OK,现在让我们来看看前后布局的对比:

进击的RecyclerView入门二(来点小装饰?)-LMLPHP

进击的RecyclerView入门二(来点小装饰?)-LMLPHP

是不是发现了其中微妙的变化?产品经理A这下应该满意了吧?

demo完整源码地址:

https://github.com/ZhangQinglian/RecyclerViewAdvance

05-11 18:12