How many viewholders will be created in a RecyclerView.Adapter - android

I can't understand how the RecyclerView recycle the views and reuses them if there are more than one type of views.I know that the Adapter will create two more ViewHolders for reusing.In that case,there are no more than two type of views that can be reused to present the next item in the window.But if the type of next item doesn't match either of the two types that have been recycled,there will be no views available to be reused to present the next item because the type of view it needs is still visible on the screen and cannot not be recycled.How does the system handle it ? Any and all answers are appreciated.

If there is a recycled view available that MATCHES to the new one that's becoming visible, then it will re-use. Otherwise it'll create the new object for the new view. It uses getViewType () to find that.
You can take a look at this for few more related points.

The RecyclerView will create as many ViewHolders as it needs to fill the available visible space. Recycling happens when one scrolls out of view. At that time, it will be reused for a new item scrolling into view.

The number of ViewHolders that have been created. Typically, you can figure out how many
there should be by determining how many list items fit on your screen at once and add 2 to 4
to that number. That isn't the exact formula, but will give you an idea of how many
ViewHolders have been created to display any given RecyclerView.

Related

Why recyclerview is faster than listview [duplicate]

This question already has answers here:
Android Recyclerview vs ListView with Viewholder
(7 answers)
Closed 3 years ago.
I was reading about the difference b/w recyclerview and listview and found out that recyclerview is faster than listview.
I tried to search online but not found any satisfactory answer I know it is used ViewHolder pattern and Notifying adapter but what does it does intearlly so it is faster?
Recycler View you could say is an efficient way to create list of views.
If you have 1000 items like ur contact list , and If ur visible screen can show only 10 items at once, it will Create only 10+1 (or +2) Views and as u scroll , items/views that left will be reused (not create) to show new data.
Recycler View by default does this, where as List View by default doesn't do.
There are some differences between these two views.
ListView is a bit heavy and it has a lot of responsibilities. Whenever we have to handle the list, such as to configure it in some way, the only way to do this is through the ListView object or inside the adapter.
A lot of bad things in the ListView were fixed or changed in the RecyclerView. It’s more efficient by default, the layout is separated and we have more possibilities over the data set inside the adapter.
These are some crucial differences between ListView and RecyclerView:
1 ViewHolder
The ViewHolder pattern allows us to make our list scrolling act smoothly. It stores list row views references and, thanks to this, calling the findViewById() method only occurs a couple of times, rather than for the entire dataset and on each bind view.
The RecyclerView’s adapter forces us to use the ViewHolder pattern. The creating part (inflating the layout and finding views) and updating the views is split into two methods — onCreateViewHolder() and onBindViewHolder().
The ListView, on the other hand, doesn’t give us that kind of protection by default, so without implementing the ViewHolder pattern inside the getView() method, we’ll end with inefficient scrolling in our list.
2 LayoutManager
The LayoutManager takes responsibility for layouting row views. Thanks to this, RecyclerView doesn’t have to think about how to position the row view. This class gives us the opportunity to choose the way that we want to show the row views and how to scroll the list. For example, if we want to scroll our list vertically or horizontally, we can choose LinearLayoutManager. For grids, it is more suitable to choose the GridLayoutManager.
Previously, with the use of the ListView, we were only able to create a vertical-scrolling list, so it wasn’t that flexible. If we wanted grids on our list, we had to choose the other widget for that — GridView.
3 ItemDecoration
A duty of the ItemDecoration is simple in theory – add some decorations for the list row views – but in practice, it’s that simple to implement if we want to create a custom one. In this case, we should extend the ItemDecoration class and implement our solution. For example, the RecyclerView list has no dividers between rows by default and it’s consistent with the Material Design guidelines. However, if we want to add a divider for some reason, we can use DividerItemDecoration and add it to the RecyclerView. In case we use the ListView, we have to figure out rows decorations by ourselves. There is no helper class like ItemDecoration for this widget.
4 ItemAnimator
The last but not least component of RecyclerView that I want to mention is ItemAnimator. As we can expect, it’s handling row views animations like list appearance and disappearance, adding or removing particular views and so on. By default, RecyclerView’s list animations are nice and smooth. Of course, we can change that by creating our own ItemAnimator, which is also not that easy. To make it easier, we should extend the SimpleItemAnimator class and implement the methods that we need (just add animations to a ViewHolder’s views). To be honest, implementing animations on the ListView was a pain. Again, we had to figure out how we want to handle them.
5 Notifying adapter
We have a couple of cool notifiers on the RecyclerView’s adapter. We are still able to use notifyDataSetChanged() but there are also ones for particular list elements, like notifyItemInserted(), notifyItemRemoved() or even notifyItemChanged() and more. We should use the most appropriate ones for what is actually happening, so the proper animations will fire correctly.
Using ListView, we were able to use just notifyDataSetChanged() on the adapter and then had to handle the rest ourselves, again.
Because of ViewHolder Pattern.
Thats was the simplest answer. Now for some details.
What recycler view does is what it's name indicates "Recycle", yes it recycles items, and it does it with the help of ViewHolder Pattern.
By Using ViewHolder we do-not need to call findViewByID() every time we go through getView()method. The reference for all rows are stored in-memory. This increases the performance significantly, as findViewByID()is a heavy process.
Hope this clears your confusion.

Android: What’s the best way to implement the BaseAdapter if item content in ListView is dynamic?

In most case, we need to implement the BaseAdapter’s getItemViewType() and getViewTypeCount() for dynamic item content of the listview, as this post says. But I think this solution is only suitable for finite number and knowing beforehand, such as listview item with sending layout and receving layout.
What about the case that the listview with its item content impossible knowing beforehand?
For example, I need to show a contact list from server, the contact list size is about several thousand. For each item, I need to show, for example, the hobby “list”. It is a small range of 0 to tens of string. So in this case:
The item types is relatively bigger than normal case using “getItemViewType”
Though each item may be different, but similar to a certain degree: the item content is different in the number of views, but common in view type. Item A is different from item B only because it have more TextViews.
For each time in the getView, the convertview is hard to simply reuse because they are different, but if we create new TextView and added to the convertView, it will impact the scrolling of the listview. I don't think it's appropriate such way. What should i do in such case?
Unfortunately you cannot easily change the number of item view types on the fly. The getViewTypeCount() method is only invoked when the adapter is set on the ListView. That means, were you to dynamically change it, then you would have to call setAdapter() again. This is a huge performance hit as the ListView will toss out all the recycled views and re-generate everything from scratch again.
Honestly, it looks like you should be using an ExpandableListView instead. It allows you to displays lists of items under groups. The only difference is the groups are placed on top of the list. So where you have A, B, C, D on the left side in your picture...in the ExpandableListView it'll sit on top.
The ExpandableListView can easily handle your situation where a given grouping could have any variable number of items within it. You mentioned needing to store a contact list. I'd suggest taking a look at a RolodexArrayAdapter for use with the ExpandableListView. It may be of help.

ListView holder with a dynamic number of elements

Here is the problem i am facing. I am developing a custom list view in which a single list view item is consisted of multiple text and image views. But depending on the item properties it sometimes needs to have 4 TextViews sometimes 1, sometimes 6.... the number is dynamic and i am having trouble figuring out how to developed a proper view holder pattern that will work.
I can not solve the problem by creating a number of TextViews and hiding them and displaying when necessary, since i dont know how many of them are necessary per item.
And inflating them dynamically and adding to the layout every time in getView is disastrous to say the least :(
Is it a viable solution to have an array list of Views in the holder and then work something out?
I'd recommend using the adapters view types: getItemViewType() and getViewTypeCount()
The number of view types depends on how many permutations are needed to represent all the varying ways an individual list item will look.
So if there are 4 different UI looks, then you'd have 4 different view types. You'd then have a ViewHolder representing each type. Then in the getView(), you just detect which type is represented by the position and inflate/populate as needed. You won't need to worry about hiding different portions of the UI to change up the look. The adapter will ensure you are only given a recycled view for the proper type.
For a nice detailed explanation of using the view type, check out this post.

How to get all children (visible and invisible) from a ListView?

My problem is similar to ListView getChildAt returning null for visible children, but despite searching I cannot find a solution.
I have a ListView with a Scroll. The ListView has 10 items, 7 of which are visible and 3 are hidden by scroll. I also have an external method (out of adapter) that must get all of the children from this ListView (e.g. using getChildAt()).
I need all 10 of the items, but the last 3 are null objects. I've tried code like the following:
getListView().smoothScrollToPosition();
But this doesn't work.
I think that I don't need to post the rest of my code, as the description says everything?
As you have already seen you can't get all the child row views from a ListView simply because a ListView holds only the views for the visible rows(plus some recycled rows but you can't reach those). The correct way to do what you want is to store whatever data in the adapter's data and retrieve it from there.
But the ListView doesn't keep the current values from RadioGroup in
running time.
I've seen that you have some problems with this so I've adapted some old code to build a basic example, code that you can find here.
I don't think so you need to add scroll view for a listView. Scroll automatically works on ListView. Try your application without adding scroll view and I'm sure it'll work as you needed.
The reason those children are null it's because they really do not exist and they will never exist, if only 7 children are on the screen at one time, the system will only create 7 and re-use by passing the convertView back to the adapter getView() method.
If you want to grab information regarding your whole dataset you should search on the dataset itself, instead of the views on the screen. E.g. if it's an ArrayAdapter, loop the array; if it's a CursorAdapter, loop the cursor; etc.
The non-visible children of a listView don't actually exist. When they become visible, one of the redundant views is recycled or a new view is generated. So you can't actually access all the views. Why do you want to? Whatever changes you want to make should be made to the data that populates the views rather than the views themselves.
There are a few point that you need to take care of:
1. List view provides inbuilt scroll functionality, So don't use Scroll view. It will only mess up things.
2. List view doesn't contain ALL the children. When you scroll it, it creates only visible items on run time.
3. If you want to get all the children altogether, Better keep an ArrayList of the child objects that your list has. You can add or remove children to this ArrayList as per requirement.

ListView's contents scrambled on scroll

So I am having a problem with the different pieces of that make up my ListView. I put them into an ArrayList and use a custom ArrayAdapter to hook up to the ListView, which I have done before so I don't believe there is a problem there. Initially the list seems to have the pieces in the correct order, but then I will scroll down the list and the contents will then load in incorrect order. I then scroll back up and everything is jumbled. Has anyone run into this before?
Thanks
-Jake
Yes your problem is related to the fact that List reuses the views for each row. So say your list can see 5 items, but your ListAdapter has 15 things in it. Android will create 5 + 1 instances of your row view instead of 15. One for each row in the list + 1 for when half of the top and bottom can be seen. When a row is moved out of the visible area the List will recycle that view instance for another row instead of creating a new one. If you don't properly reset all of the user interface components every time you'll get artifacts from other rows showing up. You must make sure that every time you bind your data from the objects in your array list to the view you set every field every time.
For a better description of this see
http://www.youtube.com/watch?v=N6YdwzAvwOA&feature=related

Categories

Resources