Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scrolling through ListView with some images very laggy

I've got the below screen that contains some images (6 per visible page). Scrolling up and down seems quite laggy to me. It's like it's rendering the images again. Scrolling back up seems worse than scrolling down.

Anyone know how to increase performance in such an area to create a nice smooth scroll?

Update: The images and text is all retrieved from my SQLite database. The list is created using SimpleCursorAdapter.

Gallery

private class HistoryViewBinder implements SimpleCursorAdapter.ViewBinder 
{
    //private int wallpaperNumberIndex;
    private int timeIndex;
    private int categoryIndex;
    private int imageIndex;

    private java.text.DateFormat dateFormat;
    private java.text.DateFormat timeFormat;
    private Date d = new Date();

    public HistoryViewBinder(Context context, Cursor cursor) 
    {
        dateFormat = android.text.format.DateFormat.getDateFormat(context);
        timeFormat = android.text.format.DateFormat.getTimeFormat(context);

        //wallpaperNumberIndex = cursor.getColumnIndexOrThrow(HistoryDatabase.KEY_WALLPAPER_NUMBER);
        timeIndex = cursor.getColumnIndexOrThrow(HistoryDatabase.KEY_TIME);
        categoryIndex = cursor.getColumnIndexOrThrow(HistoryDatabase.KEY_CATEGORY);
        imageIndex = cursor.getColumnIndexOrThrow(HistoryDatabase.KEY_IMAGE);
    }

    @Override
    public boolean setViewValue(View view, Cursor cursor, int columnIndex) 
    {
        Log.d(TAG, "setViewValue");

        if (view instanceof TextView)
        {
            Log.d(TAG, "TextView");
            TextView tv = (TextView) view;

            if (columnIndex == timeIndex)
            {
                Log.d(TAG, "timeIndex");
                d.setTime(cursor.getLong(columnIndex));
                tv.setText(timeFormat.format(d) + "  " + dateFormat.format(d));
                return true;
            }
            else if (columnIndex == categoryIndex)
            {
                Log.d(TAG, "categoryIndex");
                tv.setText(cursor.getString(columnIndex));
                return true;
            }
        }
        else if (view instanceof ImageView)
        {
            Log.d(TAG, "ImageView");
            ImageView iv = (ImageView) view;

            if (columnIndex == imageIndex)
            {
                Log.d(TAG, "imageIndex");
                byte[] image = cursor.getBlob(columnIndex);
                Bitmap bitmapImage = BitmapFactory.decodeByteArray(image, 0, image.length);
                iv.setImageBitmap(bitmapImage);
                return true;
            }
        }

        return false;
    }
}
like image 812
mlevit Avatar asked Sep 06 '10 12:09

mlevit


2 Answers

The problem is that each image is decoded at the moment the view is prepared for showing. The ListView will recycle your views that means that at the moment a view leaves the screen it will be reused and therefore the image will be overwritten and garbage collected. If the item reenters the screen the image has to be decoded from the database again.

The decoding is reasonable fast but if the user changes the position in the list very quickly all the decoding calls will make your list very laggy.

I would implment something like an ImageCache. A class that holds a Map with WeakReferences to images. Everytime you want to display an image you take a look if the image is allready in the map and if the WeakReference still points to an object, if this is not the case you need to decode the image and then store it in the map.

Take a look at the lazy loading questions, these will show you how to put the decoding in a background task and then update the list the moment the images are loaded. It is a bit more effort but it can make the list much much more faster. If you are going to use the code example from the lazy loading questions try to use AsyncTasks instead of Threads to do the decoding in.

like image 88
Janusz Avatar answered Nov 15 '22 10:11

Janusz


Here is sth, what you should read, and it should help you to solve problem (whole Displaying Bitmaps Efficiently part): http://developer.android.com/training/displaying-bitmaps/process-bitmap.html

like image 24
Krystian Avatar answered Nov 15 '22 10:11

Krystian