*** Updated hints ****
You aren't implementing getViewTypeCount() and getItemViewType() correctly.
Read the tutorial I provided in links below. I don't want to re-explain them as I'll do a worse job of it. But read below first, because you don't really need that as you only have 1 view type.
Option 1: Create 16-different rows with the correct resource image. Then call getItemViewType(position) inside the getView() method. Do a switch on it, and inflate the correct row based on the view type it returns. (Tutorial will explain this). That way you don't have to keep calling the "setImageResource" call, which is expensive.
Option 2: Based on your view holder, it appears that you only have 1 view and you are simply changing 3 text fields and 2 bitmaps. But each bitmap call is heavy, you need to create a HashMap to cache those icons. With each call, reference the hash map, if the item doesn't exist, create it, add it, and proceed. This is important because each call to setImageResource() is doing a bitmap decode and will take time. That is where you real error is See pseudo code below.
private static HashMap<Integer, Bitmap> cache;
static class BitmapCache {
public static Bitmap get(Integer id) {
if (cache.containsKey(id)) {
return cache.get(id);
} else {
Bitmap t = BitmapFactory.decodeResource(getContext(), id);
cache.put(key, t);
return t;
}
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder item = null;
Object o = getItem(position);
View mRow = convertView;
if (mRow == null) {
LayoutInflater li = LayoutInflater.from(getContext());
switch (getItemViewType(position)) {
case VIEW_ONLINE:
mRow = li.inflate(R.layout.row_online, parent, false);
break;
default:
// default to sortable
mRow = li.inflate(R.layout.row_offline, parent, false);
break;
}
item = new ViewHolder(mRow);
mRow.setTag(item);
} else {
item = (ViewHolder) mRow.getTag();
}
item.icon.setImageBitmap(BitmapCache.get(object.key));
return mRow;
}
* Old answer with tutorials *
There are several posts on StackOverflow already that I just went through yesterday related to this. (See links below).
- Yes, use getItemViewType() to retrieve the correct view type. As I understand it, the real benefit here is in the view optimization during the getView() call. Implementing getItemViewType() allows the getView() type to return the correct cached view.
- Use the static view holder pattern for text and image views inside your inflated view.
You shouldn't be inflating the view every time, you should be reusing the convertView provided by the getView() call.
- Be sure to implement getViewTypeCount()
Here is a tutorial that explains in depth how to perform custom list views including optimizations.
http://www.vogella.com/articles/AndroidListView/article.html
Here are two stackoverflow posts which also discuss what you are trying to do:
1. Android Programming tutorials - Tutorial 5
2. Restaurant Program Tutorial
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…