The problem comes from your convertView: it's the same single instance that is used throughout the list, so when your asynchronous loading is complete, the image is changed when the listview is trying to paint a different item using the same convertView (or in that case, its child imageView).
painting position 1, uses placeholder, starts loading image 1 asynchronously
painting position 2, uses placeholder, starts loading image 2 asynchronously
image 1 loading is complete, calling setImageBitmap on imageView
painting position 3, uses image 1, starts loading image 3 asynchronously
etc.
What you can do though is keep a cache of Bitmaps in the listadapter. Something like this:
private Bitmap[] bitmapList;
private Bitmap bitmapPlaceholder;
private void initBitmapListWithPlaceholders(){
// call this whenever the list size changes
// you can also use a list or a map or whatever so you
// don't need to drop all the previously loaded bitmap whenever
// the list contents are modified
int count = getListCount();
bitmapList = new Bitmap[count];
for(int i=0;i<count;i++){
bitmapList[i]=bitmapPlaceholder
}
}
private void onBitmapLoaded(int position, Bitmap bmp){
// this is your callback when the load async is done
bitmapList[position] = bmp;
}
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ImageView imageView;
TextView textView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.drink_list_row, null);
}
Drink drink = allItems.get(position);
if (drink != null && v != null) {
imageView = (ImageView) v.findViewById(R.id.picture);
textView = (TextView) v.findViewById(R.id.drinkName);
imageView.setVisibility(View.GONE);
imageView.setImageBitmap(bitmapList[position]);
loadImageBitmap(drink, position); // this should call onBitmapLoaded(int position, Bitmap bmp) when finished to update the bitmapList and replace the placeholder
textView.setText(drink.getName());
if (subItems != null && subItems.contains(drink)) {
textView.setVisibility(View.VISIBLE);
imageView.setVisibility(View.VISIBLE);
} else {
textView.setVisibility(View.GONE);
imageView.setVisibility(View.GONE);
}
}
return v;
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…