[Android Software Development] ChemDroid:
Hello community,

I've got a ListActivity in my app, which shows Views including TextViews, for showing artist, title and album information of some mp3-Files (queried by my cursor), and an ImageView, for showing an albumart => Similar to the Tracklist in the music app.

Here's the code for my custom SimpleCursorAdapter and it's binding to the ListView:

void setListAdapterOverride() {
String[] fromColumns = new String[] {
AudioColumns.ARTIST,
MediaColumns.TITLE,
AudioColumns.ALBUM,
AudioColumns.ALBUM_ID
};
int[] toColumns = new int[] {
R.id.tv_artist,
R.id.tv_title,
R.id.tv_album,
R.id.iv_albumArt
};
cursorAdapter = new customAdapter(getBaseContext(), R.layout.listviewitem, cursor, fromColumns, toColumns);
setListAdapter(cursorAdapter);
if (MyDebug.Log)
Log.d("Activity", "ListAdapter gesetzt");
}

class customAdapter extends SimpleCursorAdapter {

int layout;
Cursor cursor;
String[] from;
int[] to;

public customAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
this.layout = layout;
this.cursor = c;
this.from = from;
this.to = to;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = getLayoutInflater();
row = inflater.inflate(R.layout.listviewitem, parent, false);
if (MyDebug.Log)
Log.d("Activity", "Inflate");
}
cursor.moveToPosition(position);
TextView artist = (TextView) row.findViewById(to[0]);
TextView title = (TextView) row.findViewById(to[1]);
TextView album = (TextView) row.findViewById(to[2]);
ImageView albumArt = (ImageView) row.findViewById(to[3]);
artist.setText(cursor.getString(cursor.getColumnIndex(from[0])));
title.setText(cursor.getString(cursor.getColumnIndex(from[1])));
album.setText(cursor.getString(cursor.getColumnIndex(from[2])));

Cursor albumArtCursor = contentResolver.query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, new String[] { MediaStore.Audio.Albums._ID, MediaStore.Audio.Albums.ALBUM_ART }, MediaStore.Audio.Albums._ID + "='" + cursor.getInt(cursor.getColumnIndex(from[3])) + "'", null, null);
albumArtCursor.moveToFirst();
String albumArtUri = albumArtCursor.getString(albumArtCursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART));
if (albumArtUri == null) albumArtUri = "default";
if (!imageCache.containsKey(albumArtUri)) {
Bitmap albumArtBitmap;
if (!albumArtUri.equals("default")) {
Options opts = new Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeFile(albumArtUri, opts);
Integer[] bitmapSize = new Integer[] { opts.outWidth, opts.outHeight };
Integer scaleFactor = 1;
while ((bitmapSize[0]/2 > 50) && (bitmapSize[1]/2 > 50)) {
scaleFactor++;
bitmapSize[0] /= 2;
bitmapSize[1] /= 2;
}
opts = new Options();
opts.inSampleSize = scaleFactor;
albumArtBitmap = BitmapFactory.decodeFile(albumArtUri, opts);
} else {
albumArtBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_mp_song_list);
}
imageCache.put(albumArtUri, albumArtBitmap);
}
albumArt.setImageBitmap(imageCache.get(albumArtUri));
return row;
}
}

imageCache is a Hashmap<String, Bitmap> for caching the Bitmaps, so they don't have to be decoded from file again when they had been cached before.

In a former version of the code, I didn't have the imageCache, so the albumarts were decoded from file everytime a new row has been added. That slowed down ListView-scrolling. By adding the imageCache scrolling in ListView doesn't lag that much as before, but it's lagging a bit sometimes.

Can anyone help me to further optimize my code to completely prevent lagging when I scroll the ListView?

Thanks ;) regards ChemDroid