RecyclerView出现已经有一段时间了,相信大家肯定不陌生了,大家能够通过导入support-v7对其进行使用。 
据官方的介绍,该控件用于在有限的窗体中展示大量数据集。事实上这样功能的控件我们并不陌生。比如:ListView、GridView。

那么有了ListView、GridView为什么还须要RecyclerView这种控件呢?总体上看RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoration , ItemAnimator实现令人瞠目的效果。

  • 你想要控制其显示的方式。请通过布局管理器LayoutManager
  • 你想要控制Item间的间隔(可绘制)。请通过ItemDecoration
  • 你想要控制Item增删的动画,请通过ItemAnimator
  • 你想要控制点击、长按事件,请自己写(擦,这点尼玛。

基本使用


鉴于我们对于ListView的使用特别的熟悉,对照下RecyclerView的使用代码:

ok,相比較于ListView的代码。ListView可能仅仅须要去设置一个adapter就能正常使用了。

而RecyclerView基本须要上面一系列的步骤,那么为什么会加入这么多的步骤呢?

那么就必须解释下RecyclerView的这个名字了,从它类名上看,RecyclerView代表的意义是,我仅仅管Recycler View。也就是说RecyclerView仅仅管回收与复用View,其它的你能够自己去设置。能够看出其高度的解耦,给予你充分的定制自由(所以你才干够轻松的通过这个控件实现ListView,GirdView,瀑布流等效果)。

Just like ListView

  • Activity

  • Activity的布局文件

  • Item的布局文件

这么看起来使用方法与ListView的代码基本一致哈~~ 
看下效果图:

Android RecyclerView 使用解析

看起来好丑。Item间应该有个切割线。当你去找时,你会发现RecyclerView并没有支持divider这种属性。那么怎么办。你能够给Item的布局去设置margin,当然了这种方式不够优雅,我们文章開始说了,我们能够自由的去定制它,当然我们的切割线也是能够定制的。

ItemDecoration

我们能够通过该方法加入切割线: 
mRecyclerView.addItemDecoration() 
该方法的參数为RecyclerView.ItemDecoration。该类为抽象类,官方眼下并没有提供默认的实现类(我认为最好能提供几个)。

 
该类的源代码:

当我们调用mRecyclerView.addItemDecoration()方法加入decoration的时候,RecyclerView在绘制的时候,去会绘制decorator,即调用该类的onDraw和onDrawOver方法,

  • onDraw方法先于drawChildren
  • onDrawOver在drawChildren之后,一般我们选择复写当中一个就可以。

  • getItemOffsets 能够通过outRect.set()为每一个Item设置一定的偏移量,主要用于绘制Decorator。

接下来我们看一个RecyclerView.ItemDecoration的实现类,该类非常好的实现了RecyclerView加入切割线(当使用LayoutManager为LinearLayoutManager时)。 
该类參考自:DividerItemDecoration

该实现类能够看到通过读取系统主题中的 Android.R.attr.listDivider作为Item间的切割线,而且支持横向和纵向。假设你不清楚它是怎么做到的读取系统的属性用于自身,请參考我的还有一篇博文:Android 深入理解Android中的自己定义属性

获取到listDivider以后,该属性的值是个Drawable,在getItemOffsets中,outRect去设置了绘制的范围。onDraw中实现了真正的绘制。

我们在原来的代码中加入一句:

ok,如今再执行,就能够看到切割线的效果了。

Android RecyclerView 使用解析

该切割线是系统默认的。你能够在theme.xml中找到该属性的使用情况。

那么,使用系统的listDivider有什么优点呢?就是方便我们去任意的改变,该属性我们能够直接声明在:

然后自己写个drawable就可以。以下我们换一种分隔符:


如今的样子是:

Android RecyclerView 使用解析

当然了,你能够依据自己的需求,去任意的绘制,反正是画出来的,随便玩~~

ok。看到这,你可能认为。这玩意真尼玛麻烦,全然不能比拟的心爱的ListView。那么继续看。

LayoutManager

好了,上面实现了类似ListView样子的Demo。通过使用其默认的LinearLayoutManager。

RecyclerView.LayoutManager吧,这是一个抽象类,好在系统提供了3个实现类:

  1. LinearLayoutManager 现行管理器,支持横向、纵向。

  2. GridLayoutManager 网格布局管理器
  3. StaggeredGridLayoutManager 瀑布就式布局管理器

上面我们已经初步体验了下LinearLayoutManager。接下来看GridLayoutManager。

  • GridLayoutManager

我们尝试去实现类似GridView,秒秒钟的事情:

仅仅须要改动LayoutManager就可以。还是非常nice的。

当然了,改为GridLayoutManager以后,对于切割线,前面的DividerItemDecoration就不适用了。主要是由于它在绘制的时候。比方水平线,针对每一个child的取值为:

由于每一个Item一行。这样是没问题的。而GridLayoutManager时,一行有多个childItem,这样就多次绘制了。而且GridLayoutManager时。Item假设为最后一列(则右边无间隔线)或者为最后一行(底部无切割线)。

针对上述,我们编写了DividerGridItemDecoration

主要在getItemOffsets方法中,去推断假设是最后一行。则不须要绘制底部;假设是最后一列,则不须要绘制右边。整个推断也考虑到了StaggeredGridLayoutManager的横向和纵向,所以稍稍有些复杂。

最重要还是去理解。怎样绘制什么的不重要。一般假设不过希望有空隙,还是去设置item的margin方便。

最后的效果是:

Android RecyclerView 使用解析

ok。看到这。你可能还认为RecyclerView不够强大?

可是假设我们有这么个需求。纵屏的时候显示为ListView,横屏的时候显示两列的GridView,我们RecyclerView能够轻松搞定,而假设使用ListView去实现还是须要点功夫的~~~

当然了,这仅仅是皮毛,以下让你心服口服。

  • StaggeredGridLayoutManager

瀑布流式的布局,事实上他能够实现GridLayoutManager一样的功能,只依照下列代码:

这两种写法显示的效果是一致的,可是注意StaggeredGridLayoutManager构造的第二个參数传一个orientation,假设传入的是StaggeredGridLayoutManager.VERTICAL代表有多少列;那么传入的假设是StaggeredGridLayoutManager.HORIZONTAL就代表有多少行,比方本例假设改为:

那么效果为:

Android RecyclerView 使用解析

能够看到,固定为4行,变成了左右滑动。有一点须要注意,假设是横向的时候,item的宽度须要注意去设置,毕竟横向的宽度没有约束了,应为控件能够横向滚动了。

 
假设你须要一样横向滚动的GridView,那么恭喜你。

ok。接下来准备看大招,假设让你去实现个瀑布流,最起码不是那么任意就能够实现的吧?可是。假设使用RecyclerView。分分钟的事。 
那么怎样实现?事实上你什么都不用做。仅仅要使用StaggeredGridLayoutManager我们就已经实现了,仅仅是上面的item布局我们使用了固定的高度,以下我们仅仅在适配器的onBindViewHolder方法中为我们的item设置个随机的高度(代码就不贴了,最后会给出源代码下载地址)。看看效果图:

Android RecyclerView 使用解析

是不是棒棒哒。通过RecyclerView去实现ListView、GridView、瀑布流的效果基本上没有什么差别,并且能够只通过设置不同的LayoutManager就可以实现。

还有更nice的地方,就在于item添加、删除的动画也是可配置的。接下来看一下ItemAnimator。

ItemAnimator

ItemAnimator也是一个抽象类,好在系统为我们提供了一种默认的实现类,期待系统多 
加入些默认的实现。

借助默认的实现,当Item加入和移除的时候。加入动画效果非常easy:

系统为我们提供了一个默认的实现,我们为我们的瀑布流加入以上一行代码,效果为:

Android RecyclerView 使用解析

假设是GridLayoutManager呢?动画效果为:

Android RecyclerView 使用解析

注意,这里更新数据集不是用adapter.notifyDataSetChanged()而是 
notifyItemInserted(position)notifyItemRemoved(position) 
否则没有动画效果。 
上述为adapter中加入了两个方法:

Activity中点击MenuItem触发:

好了。到这我对这个控件已经不是一般的喜欢了~~~

当然了仅仅提供了一种动画,那么我们肯定能够去自己定义各种nice的动画效果。 
高兴的是。github上已经有非常多类似的项目了,这里我们直接引用下:RecyclerViewItemAnimators,大家自己下载查看。 
提供了SlideInOutLeftItemAnimator,SlideInOutRightItemAnimator
SlideInOutTopItemAnimator,SlideInOutBottomItemAnimator等动画效果。

Click and LongClick

只是一个挺郁闷的地方就是,系统没有提供ClickListener和LongClickListener。 
只是我们也能够自己去加入,仅仅是会多了些代码而已。 
实现的方式比較多。你能够通过mRecyclerView.addOnItemTouchListener去监听然后去推断手势。 
当然你也能够通过adapter中自己去提供回调,这里我们选择后者,前者的方式,大家有兴趣自己去实现。

那么代码也比較简单:

adapter中自定义了个接口,然后在onBindViewHolder中去为holder.itemView去设置对应 
的监听最后回调我们设置的监听。

最后别忘了给item加入一个drawable:

Activity中去设置监听:

測试效果:

Android RecyclerView 使用解析

ok,到此我们基本介绍了RecylerView常见使用方法。包括了:

  • 系统提供了几种LayoutManager的使用;
  • 怎样通过自己定义ItemDecoration去设置切割线,或者一些你想作为分隔的drawable,注意这里 
    巧妙的使用了系统的listDivider属性,你能够尝试加入使用divider和dividerHeight属性。
  • 怎样使用ItemAnimator为RecylerView去加入Item移除、加入的动画效果。

  • 介绍了怎样加入ItemClickListener与ItemLongClickListener。

能够看到RecyclerView能够实现:

  • ListView的功能
  • GridView的功能
  • 横向ListView的功
  • 横向ScrollView的功能
  • 瀑布流效果
  • 便于加入Item添加和移除动画

整个体验下来,感觉这样的插拔式的设计太棒了。假设系统再能提供一些经常使用的分隔符,多加入些动画效果就更好了。

通过简单改变下LayoutManager,就能够产生不同的效果,那么我们能够依据手机屏幕的宽度去动态设置LayoutManager,屏幕宽度一般的,显示为ListView;宽度稍大的显示两列的GridView或者瀑布流(或者横纵屏幕切换时变化。有点意思~)。显示的列数和宽度成正比。甚至某些特殊屏幕。让其横向滑动~~再选择一个nice的动画效果,相信这样的插件式的编码体验一定会让你迅速爱上RecyclerView。


相关文章: