7

I'm having hard time understanding working of view holder, here are my some question that could increase my understanding of viewholder:

It is said that oncreateViewHolder returns viewholder object, What is viewholder object does it contain all the views in single row? if there is list of 1000 item how many viewobjects will be created?

My understanding: If we are creating viewholder object it contains reference of view like findviewbyid, since findviewbyid is expansive operation, so by viewholder we can create single viewholder object and reuse by just setting image or text(happens in onBindView).

But onCreateViewHolder runs multiple times and as a result findviewbyid will also execute multiple time, isn't performance issue?

Also how its different from convertView of base adapter of simple listview

Thanks!

blackHawk
  • 6,047
  • 13
  • 57
  • 100

4 Answers4

10

View holder it is thing which helps u you to reduce find view by id calls. Let give you an example.

Suppose you have 1k items, each have a 5 view you need to find by id and only 5 full items can be shown once at screen.

So, recyclerView will create 7 (5 + one not-full bottom and one not-full top) view holders. Next time when recyclerView will be scrolled it will use existing viewHolders. Exactly as name says : "RecyclerView"

So findViewById will be called 7*5=35 times. If you do not use viewHolder you would get 5*1000 = 5000 calls.

35 vs 5000, so you understood I think.

Valentun
  • 1,661
  • 12
  • 23
  • Is reusing internal to viewholder? we dnt have to maintain? also how its different fron listview convertView of listview and why we first check if its null – blackHawk Aug 06 '17 at 16:57
  • @blackHawk yeah, RecyclerView.Adapter does it for you. But if you want to know hot it works read this (at list viewHolder example, because list View does not have adapter which use view pattern by default): https://dzone.com/articles/optimizing-your-listview – Valentun Aug 06 '17 at 16:58
  • Thanks :), what about adding recycleriew library, should its version matched with appcompat library version? – blackHawk Aug 06 '17 at 17:04
  • @blackHawk no, its should not, but remember that you SHOULD keep it up-to-date, and usually, up-to-date means "the same as latest app-compat version", but not always. – Valentun Aug 06 '17 at 17:07
  • Thank you @Valia :) – blackHawk Aug 06 '17 at 17:07
  • what about in old listview? how many times findviewbyid will be called for same 1000? – blackHawk Aug 07 '17 at 04:58
  • @blackHawk as i said in previous comment, list view do not use ViewHolder pattern. But now, it recycles its items, so, findViewById() will be called "getItemView() count * findViewByid count" times. For example if you do not scroll list FindView will be called (itemsPerScreen * findViewsCount). But if you'll scroll list to the end it would be called (1000 * findViewCount) – Valentun Aug 07 '17 at 05:11
  • yeah, but in that we enforce viewholder pattern in listview by making plain separate class, am i right? – blackHawk Aug 07 '17 at 05:14
  • @blackHawk you're right, we create a plain (ussualy inner in adapter) class and then in getItemView() instaninate it (if convertView is null) and then put it as a tag to convertView – Valentun Aug 07 '17 at 05:23
  • I was reading this https://stackoverflow.com/questions/5300962/getviewtypecount-and-getitemviewtype-methods-of-arrayadapter it makes much more sense, if I follow this and if I have exactly same looking listview items then I will be called findviewbyid once – blackHawk Aug 07 '17 at 05:29
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/151232/discussion-between-valia-sergeev-and-blackhawk). – Valentun Aug 07 '17 at 05:36
4

It is said that oncreateViewHolder returns viewholder object, What is viewholder object does it contain all the views in single row? if there is list of 1000 item how many viewobjects will be created?

One ViewHolder object for one view row. One ViewHolder object is created for every time the onCreateViewHolder is called. It is called based on the number of visible items in the device. Even if you have 100 items, if ony 10 items are visible, the onCreateViewHolder will be called 10 times and there will be 10 ViewHolders. (There might be one or two extra item based on the RecyclerView optimizations because if you scroll the list, the next item should be visible instantaneously)

My understanding: If we are creating viewholder object it contains reference of view like findviewbyid, since findviewbyid is expansive operation, so by viewholder we can create single viewholder object and reuse by just setting image or text(happens in onBindView).

RecyclerView is already recycling and reusing the Views and the corresponding ViewHolders. The number of ViewHolder (and View) present at any time depends on the number visible items on the screen.

But onCreateViewHolder runs multiple times and as a result findviewbyid will also execute multiple time, isn't performance issue?

As said previously, the number of times this will be called is only for the number of visible items. When you scroll, the views and viewholders are reused. You have distinct Views for each row. So there will be distinct ViewHolder for each row.

Also how its different from convertView of base adapter of simple listview

In ListView, the convertView is the old view, which provides an option to reuse the same view for new rows as you scroll the list. But it's optional because the developer might not use the convertView at all. In RecyclerView the reusing of old views is done automatically.

Bob
  • 13,447
  • 7
  • 35
  • 45
  • Is reusing internal to viewholde? we dnt have to maintain? also how its different fron listview convertView of listview and why we first check if its null – blackHawk Aug 06 '17 at 16:57
  • Yes, reusing the old views is done automatically. I have updated the answer about the convertview. – Bob Aug 06 '17 at 17:01
  • what about adding recycleriew library, should its version matched with appcompat library? – blackHawk Aug 06 '17 at 17:03
  • Yep. It is advised to have a same version for all the support libraries - RecyclerView, appcompat v7, design, CardView... – Bob Aug 06 '17 at 17:04
  • Thank you @Bob :) – blackHawk Aug 06 '17 at 17:05
  • If there is list of 1000 items how many convertviews are created? for reuse – blackHawk Aug 07 '17 at 05:00
  • Similar to the RecyclerView. As many visible items on the screen. But I suppose RecyclerView is more efficient than ListView in reusing the old Views. – Bob Aug 07 '17 at 07:42
3

RecyclerView.ViewHolder is a helper class that holds the View of a row or rows. One or more ViewHolder is created for each viewType.

if several rows have the same ViewType then the same View can be reused for several rows.

Overriding getItemViewType(int position) is the way to have several view types. If getItemViewType returns a not used before viewType then onCreateViewHolder will be called to create a new ViewHolder.

Adapter onBindViewHolder is the place to fill the view with specific data for each row.

ADDED:

A concept must be clear: what makes a ViewHolder to be reused is that it shares the same viewType. Instead if you make getItemViewType(int position) return a different value for each row then each row will have its independent ViewHolder and view.

from56
  • 3,976
  • 2
  • 13
  • 23
  • Is reusing internal to viewholde? we dnt have to maintain? also how its different fron listview convertView of listview and why we first check if its null – blackHawk Aug 06 '17 at 16:56
  • For me that comparison does not make much sense, RecyclerView works differently, since I use RecyclerView then how ListView getView works and its convertView param is a forgotten theme. You don't need to check for null in onCreateViewHolder. – from56 Aug 06 '17 at 17:02
  • Thanks, what about adding recycleriew library, should its version matched with appcompat library version? – blackHawk Aug 06 '17 at 17:04
  • Yes,the same version for both. I added some more text to my answer. – from56 Aug 06 '17 at 17:10
  • Yeah, Thank you @Tonteria24 :) – blackHawk Aug 06 '17 at 17:16
  • so it means if listview has exactly same looking listview then their getItemViewType will be same and there will be one call to onCreateViewHolder? – blackHawk Aug 07 '17 at 05:07
  • In some circumstances onCreateViewHolder can be called several times with the same viewType for example if several of the visible rows are the same type then several view (Holder) instances are needed. – from56 Aug 07 '17 at 11:07
2

assume that you want to show a list of 1000 items and there are just 10 items visible to the user in the screen. your adapter creates 10 ViewHolder instances to show them at the same time. when user scrolls and the adapter has to show more items, instead of creating new instances of ViewHolder, it reuses items that are not visible anymore. your adapter prevents creating new Views and saves CPU time by doing so.

Mohammad Rahchamani
  • 5,002
  • 1
  • 26
  • 36
  • Is reusing internal to viewholde? we dnt have to maintain? also how its different fron listview convertView of listview and why we first check if its null – blackHawk Aug 06 '17 at 16:51
  • 2
    What you say is correct but not enough. It will not only create 10 viewholder. It will create more to achieve a smooth scroll. So you will have 10 viewholders plus a couple of more viewholders to show them as soon as the user scrolls the list. – Leandro Ocampo Aug 06 '17 at 16:53
  • 1
    @blackHawk AFAIK, reusing is internal in your adapter and there is nothing to do for you. in convertView you should setTag manually so that you'll be able to reuse it later. – Mohammad Rahchamani Aug 06 '17 at 17:00
  • thank you @Leanadro for correcting me. I wasn't sure about the exact amount. – Mohammad Rahchamani Aug 06 '17 at 17:01
  • Okay, you say there would be 10 viewholders plus a couple more viewholder? what about listview how many viewholders will be created in case of old listview? – blackHawk Aug 07 '17 at 04:55