Can anyone please explain what’s the difference between the two kinds of getView() implementation?
The first one simply check if the convertView is null; if it’s null, inflate a new View object. Then set the sub-Views with proper values.
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
if(convertView == null)
{
LayoutInflater inflater = context.getLayoutInflater();
convertView = inflater.inflate(R.layout.itemlayout, null, true);
}
ImageView image = (ImageView) convertView.findViewById(R.id.icon);
TextView text = (TextView) convertView.findViewById(R.id.name);
MyItem item = items[position];
text.setText(item.name);
if("male".equals(item.gender))
{
image.setImageResource(R.drawable.male);
}
else if("female".equals(item.gender))
{
image.setImageResource(R.drawable.female);
}
return convertView;
}
The second one is the so-called “ViewHolder” pattern. Many developers say that this method saves a lot of memory and CPU time. But the first implementation also checks the existence of the convertView. Doesn’t the first method save some memory? Can anyone explain the difference between the two implementations more deeply and clearly? Thanks very much.
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
View itemView = convertView;
if(itemView == null)
{
LayoutInflater inflater = context.getLayoutInflater();
itemView = inflater.inflate(R.layout.itemlayout, null, true);
holder = new ViewHolder();
holder.image = (ImageView) itemView.findViewById(R.id.icon);
holder.text = (TextView) itemView.findViewById(R.id.name);
itemView.setTag(holder);
}
else
{
holder = (ViewHolder) itemView.getTag();
}
MyItem item = items[position];
holder.text.setText(item.name);
if("male".equals(item.gender))
{
holder.image.setImageResource(R.drawable.male);
}
else if("female".equals(item.gender))
{
holder.image.setImageResource(R.drawable.female);
}
return itemView;
}
The second pattern creates a static instance of the ViewHolder and attach it to the view item the first time it is loaded, and then it will be retrieved from that view tag on the future calls
getView() is called very frequently, expecially when you scroll big lists of elements, in fact it is called each time a listview item becomes visible on scroll.
That prevents findViewById() to being called lots of times uselessy, keeping the views on a static reference, it is a good pattern to save some resources (expecially when you need to reference many views in your listview items).