RecyclerView 与 ListView

Posted

技术标签:

【中文标题】RecyclerView 与 ListView【英文标题】:RecyclerView vs. ListView 【发布时间】:2014-12-30 23:02:08 【问题描述】:

来自安卓开发者(Creating Lists and Cards):

RecyclerView 小部件是更高级和灵活的版本 列表视图。

好吧,听起来很酷,但是当我看到这张示例图片时,我对这两者之间的区别感到非常困惑。

上图可以由ListView使用自定义适配器轻松创建。

那么,在什么情况下应该使用RecyclerView

【问题讨论】:

first-glance-androids-recyclerview @Dev786:我建议您在此处添加一条评论,详细解释您对这个问题的许多个现有答案所缺少的内容。 8 Differences between RecyclerView and ListView 截至 2021 年,ListView 在 AndroidStudio 中列在 Legacy 下,而 RecyclerView 在 Common 下。关于哪个更容易使用的答案是模棱两可的,所以对于像我这样的新手,我想我最好从尝试 RecyclerView 开始 【参考方案1】:

RecyclerView 是作为ListView 改进创建的,所以是的,您可以使用ListView 控件创建附加列表,但使用RecyclerView 更容易:

    在向上/向下滚动时重用单元格 - 这可以通过在 ListView 适配器中实现 View Holder 来实现,但它是可选的,而在 RecycleView 中它是编写适配器的默认方式。

    将列表与其容器解耦 - 这样您就可以在运行时通过设置LayoutManager 轻松地将列表项放入不同的容器(linearLayout、gridLayout)中。

    李>

例子:

mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
//or
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 2));
    动画常见列表动作 - 动画被解耦并委托给ItemAnimator

还有更多关于RecyclerView的内容,但我认为这几点是主要的。

因此,总而言之,RecyclerView 是一种更灵活的控件,用于处理遵循关注委派模式的“列表数据”,并且只为自己留下一个任务 - 回收项目。

【讨论】:

列表视图的主要职责是 1.) 在给定区域内直观地排列项目,最好是 2.) 重复使用项目。使用 RecylerView,这分为单一职责 - 回收视图回收,并且给定 LayoutManager 在屏幕上排列项目。换句话说,回收视图不知道/关心将项目放在屏幕上的哪个位置,它只是负责回收它们。来自 android doc:“通过更改 LayoutManager,RecyclerView 可用于实现标准的垂直滚动列表、统一网格、交错网格、水平滚动集合等等。” “在向上/向下滚动时重用单元格”:据我所知这是完全错误的,因为即使在没有查看器的列表视图中也会发生这种情况。 listview中view holder的主要用途是您的代码在ListView滚动过程中可能会频繁调用findViewById(),这会降低性能。即使适配器返回一个膨胀的视图进行回收,您仍然需要查找元素并更新它们。重复使用 findViewById() 的一种方法是使用“视图持有者”设计模式。 ViewHolder 对象将每个组件视图存储在 Layout 的 tag 字段中,因此您可以立即访问它们而无需重复查找。 我想说的是,即使您在没有视图持有者的情况下实现列表视图,行也会被回收。这就是listview的属性和优势。这就是他们创建的列表视图。 他们没有做任何特别的事情,任何人都可以添加这些功能。如果需要,您可以扩展 ListView 和 baseAdapter 并向其添加任何功能。这两者实际上没有区别。【参考方案2】:

要使列表视图具有良好的性能,您需要实现持有者模式,这很容易搞砸,尤其是当您想用几种不同类型的视图填充列表时。

RecyclerView 将这种模式融入其中,使其更难搞砸。它也更灵活,可以更轻松地处理不同的布局,而不是直线,如网格。

【讨论】:

是的! ,应该有更多关于何时使用recyclerview的讨论。如果您的行具有基于模型数据动态添加的内容,并且您使用 Recycler 视图,BOOM。 您应该能够根据模型数据添加动态内容。您只需为想要支持的任何类型的内容设置不同的视图。【参考方案3】:

ListViewRecyclerView 的祖先。 ListView 有很多事情要么没做,要么做得不好。如果您要收集ListView 的缺点并通过将问题抽象到不同的域来解决问题,您最终会得到类似回收器视图的东西。以下是 ListViews 的主要问题点:

1234563即使是通过convertView 变量传入的每一行的新视图)

并没有阻止代价高昂的 findViewById 使用(即使您如上所述回收视图,开发人员也可以调用 findViewById 来更新子视图的显示内容。 ListViews 中的 ViewHolder 模式用于缓存 findViewById 调用。但是,这只有在您知道它的情况下才可用,因为它根本不是平台的一部分)

仅支持垂直滚动并显示行视图(回收器视图不关心视图的放置位置和移动方式,它被抽象为LayoutManager。因此回收器可以支持传统的ListView如上所示,以及GridView 之类的东西,但不限于此,它可以做更多的事情,但你必须做一些编程工作才能实现)。

添加/删除的动画不是我们考虑的用例。完全由您来决定如何去做(比较 RecyclerView.Adapter 类 notify* 方法产品与 ListViews 以获得一个想法)。

简而言之,RecyclerViewListView 的更灵活的版本,尽管您可能需要完成更多编码。

【讨论】:

【参考方案4】:

RecyclerView 是一个新的 ViewGroup,准备渲染任何 基于适配器的视图以类似的方式。它应该是 ListView and GridView 的继任者,可以在 latest support-v7 versionRecyclerView 已开发完成 考虑到可扩展性,因此可以创建任何类型的 您可以想到的布局,但并非没有一点麻烦 剂量。

答案来自Antonio leiva

 compile 'com.android.support:recyclerview-v7:27.0.0'

RecyclerView 确实是 powerful view 而不是 ListView 。 更多详情可以访问This page。

【讨论】:

我喜欢你回答中的这句话:这是 Android,所以事情从来都不容易这对于 Android 应用程序开发一直是这样,但我认为这只是他们设计 API 的方式以及构建 Android 应用程序的模式有问题。从理论上讲,一个好的设计应该对程序员隐藏所有可能的复杂性(但对于高级程序员来说仍然可以访问),他们通常关心的是业务逻辑、数据和其他算法,而不是努力处理与 UI 相关的问题(以及目前存在的更繁琐的问题)在 Android 开发中)。【参考方案5】:

以下是 RecyclerView 和 ListView 之间的几个关键点/差异。明智地接听电话。

如果 ListView 适合您,则没有理由迁移。如果你是 编写一个新的 UI,你可能会更好地使用 RecyclerView。

RecylerView 内置了 ViewHolder,不需要我们自己实现 就像在 listView 中一样。它也支持在特定索引处通知

诸如动画添加或删除项目之类的东西已经 在 RecyclerView 中实现,无需您执行任何操作

我们可以将布局管理器与 RecyclerView 相关联,这可以是 用于在 recycleview 中获取随机视图,而这是限制 在 ListView 中,在 ListView 中,唯一可用的视图类型是 垂直列表视图。甚至没有正式的方法来实施 水平列表视图。现在使用 RecyclerView,我们可以有一个

i) LinearLayoutManager - 支持垂直和水平 列表,ii) StaggeredLayoutManager - 支持 Pinterest 之类的 交错列表,iii) GridLayoutManager - 支持显示 在图库应用中看到的网格。

最好的事情是我们可以根据需要动态地完成所有这些工作。

【讨论】:

【参考方案6】:

主要优势:

ViewHolderListView 中默认不可用。我们将在getView() 中显式创建。 RecyclerView 内置了Viewholder

【讨论】:

【参考方案7】:

RecyclerView 相对于 listview 的优势:

    默认包含 ViewHolder。

    简单的动画。

    支持水平、网格和交错布局

listView 相对于 recyclerView 的优势:

    易于添加分隔线。

    可以将内置 arrayAdapter 用于简单的普通列表

    支持页眉和页脚。

    支持 OnItemClickListner 。

【讨论】:

据我了解,在执行recyclerView = view.findViewById(R.id.feed); 之类的操作后,您可以使用recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), LinearLayoutManager.VERTICAL)); 轻松地将分隔线添加到recyclerView 中 @nviens 对于列表视图,您可以在 xml 中添加分隔线、调整其高度并更改其颜色。此外,当前的分隔器实现还可以,之前为 recyclerview 添加分隔器是一场噩梦,只需检查此答案即可查看分隔器的先前实现如何***.com/a/27037230/6478047【参考方案8】:

我认为它们的主要和最大区别在于ListView 在创建或放置项目时查找项目的位置,另一方面RecyclerView 查找项目的类型。如果有另一个使用相同类型创建的项目RecyclerView 不会再次创建它。它询问第一个适配器,然后询问recycledpool,如果回收池说“是的,我已经创建了一个类似的类型”,那么RecyclerView 不会尝试创建相同的类型。 ListView 没有这种池化机制。

【讨论】:

【参考方案9】:

除了以上区别之外,还有以下几点:

    RV 将视图创建和数据绑定到视图分开。 在 LV 中,在将数据绑定到它之前,您需要检查 convertView 是否为 null 以创建视图。 因此,在 RV 的情况下,只会在需要时创建视图,但在 LV 的情况下,可能会错过对 convertview 的检查,并且每次都会创建视图。

    现在使用 LayoutManager 可以更轻松地在 Grid 和 List 之间切换。

    无需通知和更新所有项目,即使仅更改单个项目。

    在 LV 的情况下必须实现视图缓存。 它默认在 RV 中提供。 (视图缓存和回收是有区别的。)

    在 RV 的情况下非常简单的项目动画。

【讨论】:

【参考方案10】:

回收站查看信息

RecyclerView 是与Android 5.0 (Lollipop) 一起引入的。它包含在Support Library 中。因此,它与 Android API Level 7 兼容。

类似于ListViewRecyclerView’s 的主要思想是以性能友好的方式提供列表功能。此视图名称中的“回收站”部分并非巧合。 RecyclerView 实际上可以回收它当前正在使用的项目。回收过程是通过称为View Holder 的模式完成的。

RecyclerView 的优缺点

优点:

用于添加、更新和删除项目的集成动画 使用 ViewHolder 模式强制回收视图 同时支持网格和列表 支持垂直和水平滚动 可与 DiffUtil 一起使用

缺点:

增加了复杂性 没有 OnItemClickListener

列表视图信息

ListView 自 Android 诞生之初就已存在。它甚至可以在API Level 1 中使用,并且与RecyclerView 具有相同的用途。

ListView 的使用其实很简单。在这方面,它不像它的继任者。学习曲线比 RecyclerView 更平滑。因此,更容易掌握。我们不必处理 LayoutManager、ItemAnimator 或 DiffUtil 之类的东西。

ListView 的优缺点

优点:

简单用法 默认适配器 可用的 OnItemClickListener 这是ExpandableListView 的基础

缺点:

不支持使用 ViewHolder 模式

【讨论】:

【参考方案11】:

在我看来,RecyclerView 是为了解决列表视图中使用的回收模式的问题,因为它使开发人员的生活更加困难。 所有其他你可以处理或多或少。 例如,我对ListViewGridView 使用相同的适配器,在两个视图中都使用getViewgetItemCountgetTypeCount 并不重要,所以它是相同的。 如果ListViewListAdapterGridView 与网格适配器已经为您工作,则不需要RecyclerView。 如果您在列表视图中正确实现了ViewHolder 模式,那么您将不会看到比RecycleView 有任何重大改进。

【讨论】:

【参考方案12】:

我曾与RecyclerView 合作过,但我仍然更喜欢ListView

    当然,他们都使用ViewHolders,所以这不是优势。

    RecyclerView 编码难度更大。

    RecyclerView 不包含页眉和页脚,因此是减号。

    ListView 不需要创建 ViewHolder。如果您想要一个包含部分或子标题的列表,最好制作独立的项目(没有 ViewHolder),这更容易并且不需要单独的类。

【讨论】:

你可以在recyclerview适配器中制作header和content side,它会比listview更灵活。只是很难改变你的想法 listview 到 recyclerview 但如果你能做到这一点,你就会明白我的意思。不推荐使用 listview 去尝试学习 recyclerview 祝你好运 @erginduran,我两个都用过。 ListView 仍然被广泛使用并且没有被弃用。而且它比 RecyclerView 浪费更少的内存。如果只想用 RecyclerView 替换 ListView,那可不是个好主意。 看看这些家伙为什么开发recyclerview?它对listview的改进,对吧? google play 中有很多旧的库和应用程序,所以你是对的,listview 仍然被广泛使用。把旧的东西留在过去。检查比较 -> link @erginduran,谢谢。你是对的,RecyclerView 有一些优势。我的回答是关于通常的任务,其中 ListView 有时比 RecyclerView 更容易。当然,动画和其他一些改进在 ListView 中是困难的或不可能的。 我在该主题中添加了一些方面,请参阅***.com/a/39721769/2914140。【参考方案13】:
    您可以使用接口来提供点击侦听器。我用这个 也可以使用 ListViews 技术。 无分隔线:只需在行中添加一个宽度为 match_parent 和 1dp 的高度,并给它一个背景颜色。 只需使用 StateList 选择器作为行背景。 在 ListViews 中也可以避免 addHeaderView:只需将 视图之外的标题。

所以,如果您关心效率,那么是的,将 ListView 替换为 RecyclerView 是个好主意。

【讨论】:

【参考方案14】:

ListView 和 RecyclerView 有很多不同,但是你应该特别注意以下几点:

ViewHolder 模式在 ListView 中完全是可选的,但它已融入 RecyclerView。 ListView 只支持垂直滚动,但 RecyclerView 不限于垂直滚动列表。

【讨论】:

【参考方案15】:

我只想强调 RecyclerView 是兼容性包的一部分。这意味着每个应用程序都没有使用操作系统的功能和代码,而是拥有自己的 RecyclerView 实现。潜在地,类似于 RecyclerView 的功能可以成为未来操作系统的一部分,并且从那里使用它可能是有益的。例如 Harmony OS 即将推出。兼容性包许可证将来可能会更改,这可能是一种暗示。缺点总结:

    许可 更大的足迹,尤其是作为许多应用程序的一部分 如果来自操作系统的某些功能可能存在,则会降低效率

但值得注意的是,一些功能的实现,如滑动项目,来自 RecyclerView。

以上所有内容都必须考虑在内。

【讨论】:

【参考方案16】:

简单的回答:你应该在你想要显示很多项目的情况下使用 RecyclerView,并且它们的数量是动态的。只有在项目数始终相同且受限于屏幕大小时,才应使用 ListView。

您会发现它更难,因为您只考虑 Android 库。

现在有很多选项可以帮助您构建自己的适配器,从而可以轻松构建动态项目的列表和网格,您可以选择、重新排序、使用动画、分隔线、添加页脚、页眉等。

不要害怕并尝试使用 RecyclerView,您会开始喜欢它,在 ListView 和 RecyclerView 中制作从网络下载的 100 个项目(如 facebook 新闻)的列表,您会看到不同之处UX(用户体验)当您尝试滚动时,测试应用可能会在您完成之前停止。

我建议您检查这两个库以制作简单的适配器:

FastAdapter by mikepenz

FlexibleAdapter by davideas

【讨论】:

我认为您关于两者之间的性能差异的陈述被夸大了。自 2012 年以来,我一直在生产应用程序中使用 ListView,每行显示多达 3000 个项目,每行有大约 10 个不同的视图,即使在旧的 Android 2.3 设备上也绝对没有性能问题。

以上是关于RecyclerView 与 ListView的主要内容,如果未能解决你的问题,请参考以下文章

RecyclerView 与 ListView

RecyclerView与CoordinatorLayout 抽屉效果无法触发的问题

RecyclerView小结

如何使布局与recyclerview一起滚动

为啥 overScrollBy() 和 onOverScrolled() 不能与 RecyclerView 一起使用

recyclerview图像捕捉与大图像中间