为什么ViewHolder模式有效?

时间:2011-05-12 06:01:14

标签: android design-patterns view

我今天学习了Android的ArrayAdapter,发现有一个commom模式,它使用ViewHolder来保存Views的引用,而不是每次调用findViewById。

但它是如何运作的?适配器通常用于显示View(Group)的列表,如果我缓存View,为什么它们都不引用最老的?

3 个答案:

答案 0 :(得分:13)

如果您想要了解ViewHolder如何运作的最佳解释,请查看Romain Guy在youtube中的Google I / O 2009演讲,特别是前15分钟。

简而言之,Adapter用作基础数据与ViewGroup之间的链接。它将根据需要渲染尽可能多的View来填充屏幕。在滚动或任何其他推动View不在屏幕外的事件时,Adapter将重复使用填充了正确数据的View来在屏幕上呈现。

getView(int pos, View view, ViewGroup parent)方法将随时使用正确的View,无论您的布局如何。我不知道这个的内部,但我相信如果你有兴趣,可以浏览任何适配器的源代码(例如ArrayAdapter.java)。
ViewHolder只保留指向由Views获得的view.findViewById(int id)的指针。适配器负责返回与任何位置相对应的正确数据。

Romain's presentation的幻灯片11到13将比我能写的任何东西都清晰得多。

答案 1 :(得分:1)

抱歉,但丹尼斯的回答可能有误。 实际上,视图实例(和ViewHolders)与屏幕可以显示的数量相同

如果您的屏幕如下:

[list view]
the first item
the second item
the third item
the fourth item

您将有4个视图实例。如果您滚动屏幕,第一个将消失,但传递给getItem()为convertView,以便您创建第五个项目。

因此,您可以在第一个ViewHolder中使用引用。

答案 2 :(得分:0)

我相信列表视图下面的工作是这样的(考虑到我们只有一个项目视图类型):

做一次:

inflate item view from layout, cache it

重复每个项目:

ask adapter to fill the data into the view
draw the view on the screen
move to next item

因此您拥有从xml布局中膨胀的视图,并且可以重复用于绘制多个列表项。 ViewHolder通过保存getViewById查找来加快速度。