引言

  最近学习了一下 RecyclerView ,感觉这个控件功能很强大啊,尤其是对于我这种常年使用 ListView 的人来说,不用网上去找各种什么瀑布流或者是横向滑动的 ListView 的开源控件去了,简直方便。下面我就从几个方面来对比一下 RecyclerViewListView

1.基本用法

直接先上代码。

首先是 Listview 的代码部分:

(1)布局文件

activity_list_view_demo.xml

呃,,,貌似过于简单了,但是还是贴出来吧,对比更加全面。

(2)Activity内的代码

这样,一个ListView就完成了,我们来看看效果:


图1.适配器为ArrayAdapter的ListView

  这里我使用了ArrayAdapter来做适配器,ArrayAdapter经过了封装,性能较好,而且可以直接使用android.R.layout.simple_expandable_list_item_1 这种Android自己提供的做item的view来显示数据,十分方便,我们也可以继承重写ArrayAdapter来实现我们自定义的itemView,在使用ListView的时候,大多也都是使用ArrayAdapter来做适配器。当然,我们还可以通过继承重写BaseAdapter 的方式来做,下面我们一起看一下。(布局文件都一样,只不过我们这里需要加一个自己定义的item的view)

item_listview.xml

Activity内的代码

效果如下:


图2.适配器为BaseAdapter的ListView效果图

  上面就是ListView的代码,虽然实现了效果,但只要仔细看的朋友都会发现,每一个itemView似乎都会调用以此Adapter,然而我们上面直接在getView()方法中直接创建TextView的行为似乎有些不妥,我们的例子中数据少看不出什么端倪,但是如果是成百上千的数据,每次都要创建一次TextView就会很影响性能,这里我们介绍一个机制ViewHolder,ViewHolder是一个持有者的类,他里面一般没有方法,只有属性,作用就是一个临时的储存器,把你getView方法中每次返回的View存起来,可以下次再用。这样做的好处就是不必每次都到布局文件中去拿到你的View,提高了效率。使用ViewHolder的方式也很简单,首先我们在Activity中新建一个内部类,把你自定义的itemView中需要用到的控件都定义在里面的:

然后,我们只需改动一下getView()方法:

这样不仅提高了ListView的性能,还提高了代码的可读性。可是即使这样,我还是觉得有些不足,那就是我们还必须自己去新建这个Viewholder的类,有没有不用我们自己动手去做这件事的呢,,,,当然有,比如我们下面要说的 RecyclerView

RecyclerView 的代码部分:

(1)布局文件

activity_list_view_demo.xml

看起来似乎和ListView的差别不大,还是看看Activity内的代码来对比一下。

(2)Activity内的代码

这样,一个RecyclerView也完成了,看看效果:


图3.RecyclerView效果图

呃,,,从效果上来看,不但没什么区别,反而少了item之间的分割线,而且xml中 RecyclerView 并没有divider这个属性,虽然我们可以去item的布局文件中去加上分割线,但是这样看起来就太不专业了。其实 RecyclerView 是支持自定义间隔样式的,在Activity中加上这行代码:

让我们来看看效果:


图4.有分割线的RecyclerView

  这只是默认的分割线,我们还可以通过继承 RecyclerView.ItemDecoration 这个抽象类来自定义分割线的样式,这次就先不做细致说明了。
  这样看起来就和上面的 Listview 一模一样了。虽然外观一样了,但是通过代码的对比,我们可以总结出以下几点:
  1.RecyclerView不用进行item的复用工作,这个工作Google已经做好了
  2.RecyclerView的ViewHolder编写比Listview的更加规范化
  3.RecyclerView需要进行LayoutManager和分割线的设定

  这样看来,RecyclerViewListView也没有太大区别,但是就基本用法来说上面的效果已经可以说是 ListView的大部分“功力”了,而 RecyclerView还有更多效果。Android提供的 RecyclerView除了 线性布局 的效果,还有 网格布局瀑布流布局,而且 线性布局 还可以会横向滑动,下面我们分别简单的看一下:

(1)线性布局横向滑动

  想让线性布局横向滑动,在上面代码的基础上,只需修改三处:
  第一步,将item的xml中TextView的长宽属性调换一下,把RecyclerView控件的高改为“match_parent”(这里不做演示)
  第二步,如下:

  第三步,修改分割线属性为横向分割线:

看下效果:


图5.横向的RecyclerView

(2)网格布局

代码

效果:


图6.RecyclerView网格布局

(3)瀑布流布局

设置每个item的高度为随机的,可以让瀑布流看起来更高大上,下面直接上代码:

来看看效果:


图7.RecyclerView的瀑布流布局

虽然没设置边框,但是可以看出高度的不同。(让我很费解的是,既然有了StaggeredGridLayoutManager,为什么还要去我们自己去设置随机的高度)。
好,基本使用的对比先到这里,我们继续对比其他方面。

2.空数据的处理

  ListView 为我们提供了setEmptyView这个API来让我们处理数据源为空的情况,而RecyclerView则没有,这个步骤需要自己来做,逻辑虽然简单,但是还是没有特别方便。

3.HeaderView和FootView

  ListView 可以让我们设置HeaderView和FootView,当我们想加上一个下拉刷新的或者底部加载更多的视图的时候,可以很方便的就完成了,但是 RecyclerView 就没有为我们提供这种便利,实现起来比较麻烦。希望官方以后可以继续完善。

4.item的点击事件

  又是一个让人郁闷的地方, RecyclerView 并没有像ListView 那样为我们提供短按监听OnItemClickListener()长按监听onLongClickListener,这里有两种方法,一是直接在adapter内直接为view设置监听,二是设置mRecyclerView.addOnItemTouchListener去监听然后去判断手势, 个人觉得第一种方法既简单又直观,我会选择这种方法。下面就演示一下。

ListView的item点击事件

代码如下:

看看效果:


图8.ListView点击事件

RecyclerView的item点击事件

这里我是直接在onBindViewHolder方法中绑定的点击事件,其他地方不变:

看下效果:


图9.RecyclerView点击事件

这样处理貌似效果上都差不多,但是有个细节做的并不到位,就是没有动画效果,需要我们自己去代码中设置。

5.数据刷新

  在ListView中,我们要刷新数据就要用到 notifyDataSetChanged(),数据源更新后我们就需要用这个方法去更新在Adapter中通过这个方法去更新视图,这十分简单,但是这个方法是将所有视图都重绘,可是没有更新数据的itemView并不需要重绘,所以我们还需要自己手动操作去控制只更新数据变化的itemView。
  RecyclerView.Adapter 则我们提供了 notifyItemChanged() 用于更新单个 ItemView 的刷新,我们可以省去自己写局部更新的工作。

总结

  通过这些对比,我们大概了解了两个控件的基本使用方法和区别,以后随着我们的使用,我们会更加深入了解它们的功能以及更加深入地发掘它们的使用方法。就目前来看,两个控件并没有说哪个可以完全取代另一个,各有各的优势,我们要学会灵活运用它们,这才是对比它们的意义。
  最后感谢阅读,欢迎指正。

Tagged:

发表评论

电子邮件地址不会被公开。 必填项已用*标注