I have a simple code snippet for implementing custom listview.
My code is as follows:
WeatherAdapter.java :
public class WeatherAdapter extends ArrayAdapter<weather>{
Context mcontext;
int mlayoutResourceId;
weather mdata[] = null;
View row;
public WeatherAdapter(Context context, int layoutResourceId, weather[] data) {
super(context, layoutResourceId, data);
mlayoutResourceId = layoutResourceId;
mcontext = context;
mdata = data;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
row = convertView;
WeatherHolder holder = null;
if(row == null)
{
LayoutInflater inflater = ( (Activity) mcontext).getLayoutInflater();
row = inflater.inflate(mlayoutResourceId, parent, false);
holder = new WeatherHolder(row);
row.setTag(holder);
}
else
{
holder = (WeatherHolder)row.getTag();
}
weather w = mdata[position];
holder.txtTitle.setText(w.mtitle);
holder.imgIcon.setImageResource(w.micon);
return row;
}
WeatherHolder.java:
class WeatherHolder
{
ImageView imgIcon;
TextView txtTitle;
public WeatherHolder(View v){
imgIcon = (ImageView)row.findViewById(R.id.imgIcon);
txtTitle = (TextView)row.findViewById(R.id.txtTitle);
}
}
}
I have seen so many answers on SO and other sites and I understood the recycling mechanism of listview.
I also understood that from viewholder, we can hold the child views in the adapter and we do not have to call findViewById()
many times. So, it is for optimization.
But I have only the confusion in setTag(holder)
and getTag()
methods. From this question, I came to know that it is for making a key-value pair on multiple objects, so that we can access them easily. But, I do not understand why they are required here...because, we do not have multiple holder objects...only we have to change holder's variables each time. can we code here without using setTag
and getTag
?
can anyone explain better that what setTag
and getTag
do "here"?
tag
is a mechanism to make yourviews
remember something, that could be anobject
aninteger
astring
or anything you like.so when your
ListView
is going to create for the first time yourconvertView
isnull
. so you create a newconvertView
and put all of yourreferences
of theobjects
of thatrow
in aviewHolder
. then save yourviewHolder
into the memory of thatconvertView
(setTag).Android
takes yourconvertView
and puts it in itspool
torecycle
it andpasses
it again to you. but itspool
may not have enoughconvertViews
so it again passes a newconvertView
thatsnull
. so again the story is repeated till thepool
ofandroid
is filled up. after thatandroid
takes aconvertView
from its pool and passes it to you. you will find that its notnull
so you ask it where are my objectreferences
that I gave to you for the first time? (getTag) so you will get those and do whatever you like.More elaboration on below line
but its pool may not have enough convertViews so it again passes a new convertView thats null
android
pool
is empty when yourlistView
is going to create. so for the first item of yourlistView
it sends you aconvertView
that must be displayed. after thatandroid
saves it in itspool
, so itspool
now contains just oneconvertView
. for your second item of yourlistView
that is going to create android can not use its pool because it is actually has one element and that element is your first item and it is being shown right now so it has to pass anotherconvertView
. this process repeates untilandroid
found aconvertView
in itspool
thats not being displayed now and passes it to you.Android inflates each row till the screen filled up after that when you scroll the list it uses holder.
Lets Look in a Different Perspective:
Lets imagine that the Helicopter is the "row" while the rope is the "setTag" and the car below is "WeatherHolder", but the pilot of the Helicopter is inside that car and he/she the one managing controlling the helicopter using a "WIRED REMOTE".
When you cut the Rope Which is "setTag" the Hellicopter still fly but the pilot can no longer control it since the pilot is drop in the ground which means the pilot is now dead! (In java when an object loss its reference the Garbage Collector will collect that and free from the memory).
When you did not place or attach the rope to the car while the Helicopter is about to fly where the Pilot is sitting - you potentially loss a control on the helicopter because you are using "WIRED REMOTE".
I hope this help :).
This is where you are wrong - there is one holder per view (aka visible or cached ListView entry).