2

I learned Android's ArrayAdapter today, and find there is a commom pattern which uses a ViewHolder to hold Views' reference instead of calling findViewById everytime.

But how does it work? Adapter is usually used to display a list of View(Group)s, If I cache the View, why don't they all reference to the oldest one?

Jim G.
  • 15,141
  • 22
  • 103
  • 166
Lai Yu-Hsuan
  • 27,509
  • 28
  • 97
  • 164

3 Answers3

13

If you want the best explanation on how the ViewHolder works, check out Romain Guy's Google I/O 2009 talk in youtube , specially the first 15 minutes.

In short, the Adapter functions as a link between the underlying data and the ViewGroup. It will render as many Views as required to fill the screen. Upon scrolling or any other event that pushes a View is out of the screen, the Adapter will reuse that View, filled with the correct data, to be rendered at the screen.

The getView(int pos, View view, ViewGroup parent) method will use the right View at any time, regardless of your layout. I do not know the internals of this, but I'm sure you can browse the source code for any adapter (such as ArrayAdapter.java) if you're interested.
The ViewHolder just keeps a pointer to the Views as obtained by view.findViewById(int id). It is the Adapter responsibility to return the right data corresponding to any position.

Slides 11 to 13 of Romain's presentation will make it a lot more clear than anything I can write.

Aleadam
  • 40,203
  • 9
  • 86
  • 108
1

Sorry but denis' answer may be wrong. In fact, the view instances(and ViewHolders) are as many as your screen can display.

If your screen looks like:

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

You will have 4 instances of views. If you scroll screen, the first will disappear but be pass to getItem() as convertView for you to create the fifth item.

So you can use the references in first ViewHolder.

Lai Yu-Hsuan
  • 27,509
  • 28
  • 97
  • 164
  • This means that while drawing the first item ListView creates the view, than pass it as `convertView`. If you return the same `convertView` from `getItem`, then you have the same view again while rendering the second item.. :) There won't be two views, right? – denis.solonenko May 13 '11 at 05:31
  • I think it's... wrong. At least accroding what I heard on #android-dev. You reuse the view only after it disappeared. So you can't use first view to draw second item if your screen is bigger than one item. If there are N items on screen, there are N instances of view. – Lai Yu-Hsuan May 13 '11 at 05:45
  • after looking at the sources I have to agree that the algorithm is not that easy and straightforward as I thought. It does involve some amount of views, some of them are reusable, some are not. Will have to dig more into sources to understand what's going on.. – denis.solonenko May 13 '11 at 06:03
0

I believe the work beneath the list view is something like this (considering we have only one item view type):

do once:

inflate item view from layout, cache it

repeat for every item:

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

so you have the view which is inflated from xml layout and can be reused for drawing multiple list items. ViewHolder speeds it up a bit more by saving getViewById lookups.

denis.solonenko
  • 11,645
  • 2
  • 28
  • 23
  • so that there is only ONE View, how does it fill data to different posotions(ex. TextView)? – Lai Yu-Hsuan May 12 '11 at 08:13
  • @Lai Yu-Hsuan it takes the first item, fills all the data from adapter to textFields etc, draws this view, moves to the next item, repeats.. You don't have to have separate view objects for every item to do that – denis.solonenko May 12 '11 at 09:12
  • Oh I see. so we reuse the view:one instance, draw many times, righr? So I guess I can't access those views in view hierarchy? – Lai Yu-Hsuan May 12 '11 at 09:43
  • @Lai Yu-Hsuan yeah, that's my understanding. it decouples drawing logic from data. why would you need to access those views? – denis.solonenko May 12 '11 at 09:52
  • I don't want to do. just certify whether I understand what you said. – Lai Yu-Hsuan May 12 '11 at 10:09