theSereneRebel
theSereneRebel

Reputation: 306

How does the recyclying of rows in an listView work when working with a view holder?

I have defined a ViewHolder for my ListView rows like this:

import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
class ViewHolder 
{
ImageView icon=null;
TextView size=null;
ViewHolder(View row) 
{
   this.icon=(ImageView)row.findViewById(R.id.icon);
   this.size=(TextView)row.findViewById(R.id.size);
}
}

and the getView() method of the adapter class looks like this:

@Override
public View getView(int position, View convertView,
ViewGroup parent) {
View row=super.getView(position, convertView, parent);
ViewHolder holder=(ViewHolder)row.getTag();
if (holder==null) {
holder=new ViewHolder(row);
row.setTag(holder);
}
if (getModel(position).length()>4) {
holder.icon.setImageResource(R.drawable.delete);
}
else {
holder.icon.setImageResource(R.drawable.ok);
}
holder.size.setText(String.format(getString(R.string.size_template), items[position].length()));
return(row);
}

Now my question are:

  1. Under what circumstances will the getTag() call on the View return null?

  2. What does the row.setTag(holder) do and and how does it reinitialize the ViewHolder?

  3. How does recyclying of Views work in ListView and how does getTag() and setTag() help us with that while using an Adapter?

I am a bit confused with the working mechanism and have searched Stack Overflow without finding any results.

Upvotes: 1

Views: 66

Answers (1)

singh.indolia
singh.indolia

Reputation: 1301

This is a pretty good question.So in order to know the behaviour of Tags in an adapter we need to know the actual behavior of process flow of recycle in listView.

Tag is a gadget to make our views remember something, which could be an object, an integer or anything else, so when our ListView goes to create for the first time at that time convertView is null, so we create a new convertView and put all of our references of the row objects in a viewHolder, then save our viewHolder into the memory of that convertView(setTag). Android takes our convertView and place it in its pool memory to recycle it and passes it again to us. But its pool memory may not have enough convertViews so it again passes a new convertView thats null. So again the story is repeated till the pool of android is filled up. After that android takes a convertView from its pool and passes it to us. You will find that its not null so you ask it where are my object references that I gave to you for the first time using getTag() so you will get those and do whatever you like.

This is the process flow of list ViewHolder but if you want to know more about setTag() and getTag(), i will give you an example:

Suppose you are creating bunch of view having similar kind behavor like :

button1.setOnClickListener(new OnClickListener ... );
button2.setOnClickListener(new OnClickListener ... );

and then you will override method onClick() like:

private void onClick(View view) {
    doAction(0); // here 0 for button 1 and 1 for button 2. 
}

this is because you are getting only one parameter View in onclick() method, you can use setTag() to change its behavior using the values '0' and '1' to access the different button : just add

button1.setTag(0);
button2.setTag(1);

Now you can use the same OnClickListener for every button by getting the tag attached to the View by using the function getTag():

listener = new OnClickListener() {
    @Override
    public void onClick(View view) {
        doAction(view.getTag());
    }
};

this is because you are putting your views into the pool memory by using setTag() method and then getting these views from pool accordingly.

Upvotes: 1

Related Questions