我很难理解视图持有者的工作,这是我的一些问题,可以增加我对视图持有者的理解:
据说oncreateViewHolder返回viewholder对象,什么是viewholder对象,它包含单行中的所有视图吗?如果有 1000 个项目的列表,将创建多少个视图对象?
我的理解: 如果我们创建viewholder对象,它包含像findviewbyid这样的视图引用,因为findviewbyid是扩展操作,所以通过viewholder我们可以创建单个viewholder对象并通过仅设置图像或文本来重用(发生在onBindView中)。
但是onCreateViewHolder执行了多次,导致findviewbyid也会执行多次,不是性能问题吗?
还有它与简单列表视图的基本适配器的convertView有何不同
谢谢!
视图持有者它可以帮助你减少通过 id 调用查找视图。 给你举个例子吧。
假设您有 1k 个项目,每个项目有 5 个视图,您需要通过 id 查找,并且屏幕上只能显示一次完整的 5 个项目。
因此,recyclerView 将创建 7 个(5 个 + 1 个不完整的底部和 1 个不完整的顶部)视图持有者。下次当 recyclerView 滚动时,它将使用existing viewHolders。正如名称所示:“RecyclerView”
所以 findViewById 将被调用 7 * 5 = 35 次。 如果您不使用 viewHolder,您将收到 5 * 1000 = 5000 次调用。
35 vs 5000,所以我想你明白了。
据说oncreateViewHolder返回viewholder对象,什么是 viewholder 对象是否包含单行中的所有视图?如果 有 1000 个项目的列表,将创建多少个视图对象?
一个 ViewHolder 对象对应一个视图行。每次调用 onCreateViewHolder 时都会创建一个 ViewHolder 对象。它是根据设备中可见项目的数量来调用的。即使您有 100 个项目,如果只有 10 个项目可见,则 onCreateViewHolder 将被调用 10 次,并且将有 10 个 ViewHolders。 (根据 RecyclerView 优化,可能会有一个或两个额外的项目,因为如果滚动列表,下一个项目应该立即可见)
我的理解:如果我们正在创建viewholder对象,它包含 像 findviewbyid 这样的视图的引用,因为 findviewbyid 是可扩展的 操作,因此通过viewholder我们可以创建单个viewholder对象并 只需设置图像或文本即可重用(发生在 onBindView 中)。
RecyclerView 已经在回收并重用 Views 和相应的 ViewHolders。任何时候存在的 ViewHolder(和 View)的数量取决于屏幕上可见项目的数量。
但是 onCreateViewHolder 运行多次,结果 findviewbyid 也会执行多次,不是性能问题吗?
如前所述,调用的次数仅针对可见项目的数量。当您滚动时,视图和视图持有者会被重用。每行都有不同的视图。所以每一行都会有不同的ViewHolder。
还有它与简单的基础适配器的convertView有何不同 列表视图
在ListView中,convertView是旧视图,它提供了一个选项,可以在滚动列表时为新行重用相同的视图。但它是可选的,因为开发人员可能根本不使用convertView。在 RecyclerView 中,旧视图的重用是自动完成的。
RecyclerView.ViewHolder 是一个辅助类,它保存一行或多行的视图。 为每个 viewType 创建一个或多个 ViewHolder。
如果多行具有相同的 ViewType,则同一个 View 可以重复用于多行。
覆盖
getItemViewType(int position)
是拥有多种视图类型的方法。如果 getItemViewType
返回一个之前未使用过的 viewType,那么 onCreateViewHolder
将被调用来创建一个新的 ViewHolder。
适配器
onBindViewHolder
是用每行的特定数据填充视图的地方。
添加:
有一个概念必须清楚:ViewHolder之所以能够被重用,是因为它共享相同的viewType。 相反,如果您让
getItemViewType(int position)
为每行返回不同的值,那么每行将拥有其独立的 ViewHolder 和视图。
假设您要显示 1000 个项目的列表,而屏幕中用户只能看到 10 个项目。您的适配器创建 10 个 ViewHolder 实例来同时显示它们。当用户滚动并且适配器必须显示更多项目时,它不会创建 ViewHolder 的新实例,而是重用不再可见的项目。您的适配器会阻止创建新视图并通过这样做节省 CPU 时间。