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

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

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

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

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

我们先来看一下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.

All ItemDecorations are drawn in the order they were added, before the item views (in onDraw() and after the items (in onDrawOver(Canvas, RecyclerView, RecyclerView.State).

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

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

要做的很简单我们自定义一个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,现在让我们来看看前后布局的对比:



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

demo完整源码地址:

https://github.com/ZhangQinglian/RecyclerViewAdvance

进击的RecyclerView入门二(来点小装饰?)的更多相关文章

  1. 进击的RecyclerView入门三(要是能拖动就好了)

    还是接着上一讲"进击的RecyclerView入门二(来点小装饰?)",在上一讲中我们学到了怎么给不同的Item定制不同的外观,但貌似那个蓝色的框实在太丑了,咱还是把它干了吧. @ ...

  2. 进击的RecyclerView入门一(简单上手)

    虽然RecyclerView面世有一段时间了,但由于它的学习成本相对较高,很多码友只是粗略的认识了一下而没有细致的品味RecyclerView的真谛. 那么从现在开始我将带你装逼带你飞,一起领略Goo ...

  3. JAVA之旅(二十六)——装饰设计模式,继承和装饰的区别,LineNumberReader,自定义LineNumberReader,字节流读取操作,I/O复制图片

    JAVA之旅(二十六)--装饰设计模式,继承和装饰的区别,LineNumberReader,自定义LineNumberReader,字节流读取操作,I/O复制图片 一.装饰设计模式 其实我们自定义re ...

  4. IM开发者的零基础通信技术入门(二):通信交换技术的百年发展史(下)

    1.系列文章引言 1.1 适合谁来阅读? 本系列文章尽量使用最浅显易懂的文字.图片来组织内容,力求通信技术零基础的人群也能看懂.但个人建议,至少稍微了解过网络通信方面的知识后再看,会更有收获.如果您大 ...

  5. 脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?

    1.引言 本文接上篇<脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手>,继续脑残式的网络编程知识学习 ^_^. 套接字socket是大多数程序员都非常熟悉的概念,它是计算机 ...

  6. [转帖]脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?

    脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?     http://www.52im.net/thread-1732-1-1.html   1.引言 本文接上篇<脑残式网 ...

  7. MySQL概述及入门(二)

    MySql概述及入门(二) MySQL架构 逻辑架构图: 执行流程图: MySQL的存储引擎 查询数据库支持的存储引擎 执行: show engines: 多存储引擎是mysql有别于其他数据库的一大 ...

  8. 【原创】NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示

    前言 NIO框架的流行,使得开发大并发.高性能的互联网服务端成为可能.这其中最流行的无非就是MINA和Netty了,MINA目前的主要版本是MINA2.而Netty的主要版本是Netty3和Netty ...

  9. Swift语法基础入门二(数组, 字典, 字符串)

    Swift语法基础入门二(数组, 字典, 字符串) 数组(有序数据的集) *格式 : [] / Int / Array() let 不可变数组 var 可变数组 注意: 不需要改变集合的时候创建不可变 ...

随机推荐

  1. Python操作列表常用方法

    Python操作列表的常用方法. 列表常用的方法操作列表以及小例子: 1. Append 在列表末尾添加元素,需在列表末尾添加元素,需要注意几个点: A. append中添加的参数是作为一个整体 &g ...

  2. atitit.thumb生成高质量缩略图 php .net c++ java

    atitit.java thumb生成高质量缩略图 php .net c++ 1. 图像缩放(image scaling)---平滑度(smoothness)和清晰度(sharpness) 1 2.  ...

  3. location 设定某个文件的过期时间,并不记录访问日志

    网页的根目录本来是: 6 root /app/www/default; [root@web01 default]# cat /app/server/nginx/conf/vhosts/default. ...

  4. android.animation(3) - ValueAnimator-ofObject(TypeEvaluator evaluator, Object... values)

    一.ofObject()概述 前面我们讲了ofInt()和ofFloat()来定义动画,但ofInt()只能传入Integer类型的值,而ofFloat()则只能传入Float类型的值.那如果我们需要 ...

  5. python pip的安装流程,以及使用pip更新,卸载第三方模块

    在Python的学习过程中,肯定会遇到很多安装模块的地方,可以使用easy_install安装,但是easy_install相对于pip而言,最大的缺陷就是它所安装的模块是不能够卸载的,其他功能是和p ...

  6. wget镜像网站并且下载到指定目录 2012-06-20 19:40:56

    wget镜像网站并且下载到指定目录 2012-06-20 19:40:56 分类: Python/Ruby wget -r -p -np -k -P /tmp/ap http://www.exampl ...

  7. GDB和WinDbg中调用函数

    GDB: 特别简单,直接写调用式子即可,如下图的p word.c_str(),其中word的类型是std::string WinDbg:目前都说是.call命令,说实话我宁愿不用...见: http: ...

  8. 已知问题汇总 (2013-11-30) - QQ空间, EXTJS

    目前发现两个已知问题暂时无法得到解决: 1. QQ空间问题. 打开页面 http://user.qzone.qq.com/822994792/311, 点击 "xxx人赞" 这个链 ...

  9. LAMP 环境搭建关键步骤及注意事项

    一.安装MySQL1): 编译安装MySQL+----------------------------------------------------------------------------- ...

  10. 巨头们的GitHub仓库整理

    1.Google >1.Google >https://github.com/google >2.Google Samples https://github.com/googlesa ...