A little newbie question. Why should we initialize the ViewHolder in getView()? Why can’t we initialize it in the constructor?
A little newbie question. Why should we initialize the ViewHolder in getView() ? Why
Share
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
You will have multiple
ViewHolderobjects in existence.A
ListViewby its nature doesn’t create newViewinstances for each of its rows. This is so that if you have aListViewof a million things, you don’t need to store layout information for a million things. So what do you need to store? Just the things that are on the screen. You can then reuse those views over and over again. This way, yourListViewof a million objects can just have maybe 10 child views.In your custom array adapter, you will have a function called
getView()that looks something like this:This will work, but take a moment and see if you can spot the inefficiency here. Think about which of the above code will be called redundantly.
The problem is that we are calling
row.findViewByIdover and over again, even though after the first time we look it up, it will never change. While if you only have a simpleTextViewin your list, it’s probably not that bad, if you have a complex layout, or you have multiple views that you want to set data for, you could lose a bit of time finding your view over and over again.So how do we fix this? Well, it would make sense to store that TextView somewhere after we look it up. So we introduce a class called a
ViewHolder, which “holds” the views. So inside of the adaptor, introduce an inner class like so:This class is private, since it’s just a caching mechanism for the adapter, and it is static so that we don’t need a reference to the adapter to use it.
This will store our view so that we don’t have to call
row.findViewByIdmultiple times. Where should we set it? When we inflate the view for the first time. Where do we store it? Views have a custom “tag” field, which can be used to store meta-information about the view – exactly what we want! Then, if we’ve already seen this view, we just have to look up the tag instead of looking up each of the views within the row..So the if statement inside of
getView()becomes:Now, we just have to update the holder.textView’s text value, since it’s already a reference to the recycled view! So our final adapter’s code becomes:
And we’re done!
Some things to think about:
TextViewobjects and anImageViewholder.textView.getText()is before you update it at the end ofgetView()