Understanding RecyclerView.ViewHolder
Asked Answered
W

4

8

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!

Winburn answered 6/8, 2017 at 16:37 Comment(0)
H
11

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 has 5 views 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.

Heterodox answered 6/8, 2017 at 16:50 Comment(11)
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 nullWinburn
@Winburn 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): dzone.com/articles/optimizing-your-listviewHeterodox
Thanks :), what about adding recycleriew library, should its version matched with appcompat library version?Winburn
@Winburn 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.Heterodox
Thank you @Valia :)Winburn
what about in old listview? how many times findviewbyid will be called for same 1000?Winburn
@Winburn 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)Heterodox
yeah, but in that we enforce viewholder pattern in listview by making plain separate class, am i right?Winburn
@Winburn 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 convertViewHeterodox
I was reading this #5301462 it makes much more sense, if I follow this and if I have exactly same looking listview items then I will be called findviewbyid onceWinburn
Let us continue this discussion in chat.Heterodox
N
5

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.

Nd answered 6/8, 2017 at 16:55 Comment(7)
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 nullWinburn
Yes, reusing the old views is done automatically. I have updated the answer about the convertview.Nd
what about adding recycleriew library, should its version matched with appcompat library?Winburn
Yep. It is advised to have a same version for all the support libraries - RecyclerView, appcompat v7, design, CardView...Nd
Thank you @Nd :)Winburn
If there is list of 1000 items how many convertviews are created? for reuseWinburn
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.Nd
S
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.

Slating answered 6/8, 2017 at 16:53 Comment(7)
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 nullWinburn
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.Slating
Thanks, what about adding recycleriew library, should its version matched with appcompat library version?Winburn
Yes,the same version for both. I added some more text to my answer.Slating
Yeah, Thank you @Tonteria24 :)Winburn
so it means if listview has exactly same looking listview then their getItemViewType will be same and there will be one call to onCreateViewHolder?Winburn
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.Slating
K
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.

Koger answered 6/8, 2017 at 16:46 Comment(5)
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 nullWinburn
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.Winder
@Winburn 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.Koger
thank you @Leanadro for correcting me. I wasn't sure about the exact amount.Koger
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?Winburn

© 2022 - 2024 — McMap. All rights reserved.