I understand the idea and usage of Viewholder pattern, but still I have one question:
Assume we have one TextView in the viewholder, and 10 items to display ("item0, item1....").
If I call findViewById once, as I understand I have one object of that TextView.
So at first call to getView I inflate the view, find the reference and set text "item0".
At second call I get same TextView and set text "item1" to the same TextView.
Why item 0 text doesn't change?
Is there any cloning in the background?
Is there any cloning in the background?
Android preallocate a number of views that are enough to fill the screen of the device where you are running the app ( a pool of views ), identical from the content perspective but differently from the reference perspective
Assuming that you implement your ViewHolder inside an adapter class and you use the holder in the getView() method, the only thing that is for sure, is that the TextView in your case , describe a slot of the parent structure (e.g. ListView). Once you have defined the slot in an xml, that is inflated from your adapter, there is no cloning or something like that.
According to Google Documentation the holder idea is described as :
Your code might call findViewById() frequently during the scrolling of
ListView, which can slow down performance. Even when the Adapter
returns an inflated view for recycling, you still need to look up the
elements and update them. A way around repeated use of findViewById()
is to use the "view holder" design pattern.
A ViewHolder object stores each of the component views inside the tag
field of the Layout, so you can immediately access them without the
need to look them up repeatedly. First, you need to create a class to
hold your exact set of views.
There is not cloning , only reusability of the view
Related
Regarding the lisview recycle, I'm reusing the views with viewholder, but now I need to add a number of Views(ImageViews and textviews) not clearcut( the number of views isnt always the same).
How can I add these items, without create a new view on every getView() method and without affecting the performance of the list?
No way to create different layouts without overriding getView(). You can reuse as much view types as you want, read this answer.
If you have perfomance issue, try a new widjet RecyclerView, available at Support-V7 library.
my strategy to implement what you described without creating new view every time getView() is called, is:
let's say you have at the most 10 image views. your view xml will contain 10 ImageView items,
but when getView() been called - you'll set the visibility of the un-needed elements to View.GONE, and the only ones you needed to View.Visible.
working great for me, and that's the only why not to create new view...
I have one question for list view. At the time of creating list item in getView() method, which is a good option for list view. Creating views through coding or inflating view through xml. I am thinking about memory utilization & performance of list view.
Normally list item contain one product image with their name & 3 line description. Means one Image View & two text view.
Creating Views through code is usually not recommended and is justified only in cases when you can't deal without it. Using XML is always best practice so you should use this approach no matter where you're using your Views. Hope this helps.
You need to recycle views. Are you using a VieHolder?. My suggestion is use a view holder inflate using xml. ViewHolder will increase performance of ListView.
http://www.youtube.com/watch?v=wDBM6wVEO70. Check this link.
I have a serious problem with a custom view i use in an expandableListView. I use an adapter that extends BaseExpandableListAdapter. The custom view changes its state depending on if it is being consulted or modifying. The state change involves animation and show/hide of ui parts.
The problem is that even thought i let only two views, when i click on the second view i order to make it change its state, the adapter calls the getViewGroup fo the two views but systematically inverting the corresponding model data ids.. .witch makes the ui to animate again...
I precise that i don't use the viewholder pattern since the custom view has its own internal references to the controls to be updated.
Any idea would be appreciated?
i found out the solution, everytime the model changes i called notifyDataChanged() which makes the entire listview to be redrawn
I am implementing a ListView using custom adapters. To improve the performance I am returning the newly inflated View if convertView is null, else returning the recycled View.
Now in this process I used the ViewHolder pattern and used the setTag() method of the View. Initially I thought this is some kind of bookmarking but I've not completely understood the use of it. I've checked different blog post where they just used this in the code.
Can someone please explain me the use of the setTag() method?
Basically you can store any kind of object as tag (and cast it back when calling getTag). This can be a simple ID or some complex data. It's some information which you associate with this view.
In the case of lists and the view holder pattern it's a simple object which contains references to views of the tagged view (group). So you don't have to call findViewById every time when you're updating the content of the view. It's just an performance optimization.
Can we store data of list item in the view tag?
No. Because of view recycling you have (e.g.) 10 views which are reused for 1000 list items. Storing data in the tag makes no sense here. It's better to use an custom data object to store the list item state (probably the same array which contains the displayed data) or you persist it right away on list item change.
See also setTag documentation.
I have an Android app that has both CursorAdapter based ListViews (backed by sqlite) as well as custom BaseAdapter based ListViews which are built on the fly from JSON pulled down from a server.
The data displayed in both is identical - an image and a couple of TextViews. My Cursor-based ListView has 3000 rows, the JSON-based ListView has about 30. However, scrolling down the list is significantly faster for the Cursor-based adapter. For the JSON-based lists, the data is all fetched before the rows are made visible. Images for both types of lists are downloaded on-demand.
I have both ListViews configured identically - both with fastScrollEnabled, scrollingCache and smoothScrollbar set to true.
I'm looking for leads on how to go about trying to figure out what's going on here and to potentially fix it so that the JSON-based ListViews as as fast as the Cursor-based ones.
I have a similar thing in my application, except I only have json backed ListView and I also have about 30 items in it (with data constantly changing and animation playing to reflect changes).
It would be much more easier to detect a problem with some provided code from your side, but here are couple of tricks you can sue for optimization.
Reuse convertView that is passed to you as one of the parameters in getView method, it really speeds up the scrolling.
Either create your own row view (by extending some layout, or ViewGroup), or use setTag on a row you return form your getView method. In this tag, you should keep an object that contains references to views in that row, so you wont be searching for them with findViewById everytime a row is requested.
Object can be a simple static class like
private static class ViewHolder {
ImageView image;
TextView text;
}
On the first time (when the convertView is null and you need to create a fresh row) you just create instance of your ViewHolder and set those parameters to refer to parameters from your newly created row (by calling findViewById), and put this instance in row's setTag method.
Next time, when you reuse convertView, just call getTag and in the tag you recieved you'll get references to views in that row, so you won't be needing to call findViewById anymore.
Of course, you might already done all those things.
P.S. I advice you (if you haven't already) to watch Google I/O presentation about ListView's. A lot of useful information there: http://www.youtube.com/watch?v=wDBM6wVEO70