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 your views
remember something, that could be an object
an integer
a string
or anything you like.
so when your ListView
is going to create for the first time your convertView
is null
. so you create a new convertView
and put all of your references
of the objects
of that row
in a viewHolder
. then save your viewHolder
into the memory of that convertView
(setTag). Android
takes your convertView
and puts it in its pool
to recycle
it and passes
it again to you. but its pool
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 you. 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? (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 your listView
is going to create. so for the first item of your listView
it sends you a convertView
that must be displayed. after that android
saves it in its pool
, so its pool
now contains just one convertView
. for your second item of your listView
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 another convertView
. this process repeates until android
found a convertView
in its pool
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.