了解RecyclerView.ViewHolder

时间:2017-08-06 16:37:44

标签: java android listview android-recyclerview android-adapter

我很难理解视图持有者的工作,这是我的一些问题,可以增加我对观察者的理解:

据说oncreateViewHolder返回viewholder对象,viewholder对象是什么包含单行中的所有视图?如果有1000个项目的列表将创建多少个viewobjects?

我的理解: 如果我们要创建viewholder对象,它包含findviewbyid之类的视图引用,因为findviewbyid是扩展操作,所以viewholder我们可以通过设置图像或文本创建单个viewholder对象并重用(在onBindView中发生)。

但onCreateViewHolder多次运行,因此findviewbyid也会执行多次,是不是性能问题?

它与简单列表视图的基本适配器的convertView有何不同

谢谢!

4 个答案:

答案 0 :(得分:4)

查看持有者这是帮助你减少id调用查找视图的东西。 让我们举个例子。

假设您有1k个项目,每个项目都需要通过ID找到5个视图,并且在屏幕上只能显示5个完整项目。

因此,recyclerView将创建7个(5 +一个不完整底部和一个不完整顶部)视图持有者。下次循环recyclelerView时,它将使用现有 viewHolders。正如名字所说:“ Recycler 查看”

因此,findViewById将被称为7 * 5 = 35次。 如果您不使用viewHolder,您将获得5 * 1000 = 5000次呼叫。

35 vs 5000,所以你理解我认为。

答案 1 :(得分:4)

  

据说oncreateViewHolder返回视图对象,是什么   viewholder对象是否包含单行中的所有视图?如果   有1000个项目的列表将创建多少个viewobjects?

一个视图行的一个ViewHolder对象。每次调用onCreateViewHolder时都会创建一个ViewHolder对象。它是根据设备中可见项的数量调用的。即使您有100个项目,如果有10个项目可见,onCreateViewHolder将被调用10次,并且将有10个ViewHolders。 (基于RecyclerView优化可能会有一两个额外的项目,因为如果滚动列表,则下一个项目应该立即可见)

  

我的理解:如果我们正在创建它包含的viewholder对象   像findviewbyid这样的视图引用,因为findviewbyid是扩展的   操作,所以通过viewholder我们可以创建单个viewholder对象和   只需设置图像或文本即可重复使用(在onBindView中发生)。

RecyclerView已经在回收和重用视图和相应的ViewHolders。随时出现的ViewHolder(和View)数量取决于屏幕上可见项目的数量。

  

但onCreateViewHolder多次运行,结果   findviewbyid还会执行多次,是不是性能问题?

如前所述,此次调用的次数仅适用于可见项目的数量。滚动时,将重复使用视图和视图。每行都有不同的视图。因此每行都会有不同的ViewHolder。

  

它如何与简单的base适配器的convertView不同   列表视图

在ListView中,convertView是旧视图,它提供了在滚动列表时为新行重用相同视图的选项。但它是可选的,因为开发人员可能根本不使用convertView。在RecyclerView中,重复使用旧视图是自动完成的。

答案 2 :(得分:2)

假设您要显示1000个项目的列表,并且屏幕上的用户只能看到10个项目。您的适配器创建10个ViewHolder实例以同时显示它们。当用户滚动并且适配器必须显示更多项目时,它不再创建ViewHolder的新实例,而是重用不再可见的项目。您的适配器会阻止创建新视图并节省CPU时间。

答案 3 :(得分:2)

RecyclerView.ViewHolder是一个帮助类,它包含一行或多行的视图。 为每个viewType创建一个或多个ViewHolder。

如果多个行具有相同的ViewType,则可以为多个行重复使用相同的View。

覆盖getItemViewType(int position)是获得多种视图类型的方法。如果getItemViewType返回viewType之前未使用的内容,则会调用onCreateViewHolder来创建新的ViewHolder。

适配器onBindViewHolder是用每行的特定数据填充视图的地方。

<强>增加:

必须明确一个概念:使ViewHolder重用的原因是它共享相同的viewType。 相反,如果您使getItemViewType(int position)为每行返回不同的值,则每行将具有其独立的ViewHolder和视图。

相关问题