Question

I am trying to load images into my listview from a custom adapter but the Bitmaps do not display the images until I scroll down and then scroll back up and I don't know why! At first when I had loaded the images , the application crashed as I wasn't loading the Images efficiently.

(I am storing images in a DB by encoded to base64. I know it's not a great thing to do but I need to just get things done as quick as possible).

Bonus question What is the best way to trigger an event to happen after TWO asynchronous DB calls are complete?

My code to load Bitmap:

public Bitmap decodeBitmap(String image, int reqWidth, int reqHeight)
    {
        byte[] decodedByte = Base64.decode(image, 0);
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length, options);

        options.inSampleSize = calculateSize(options, reqWidth, reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        Bitmap bmp = BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length, options);
        return bmp;
    }

    public int calculateSize(BitmapFactory.Options options, int reqWidth, int reqHeight)
    {

        final int height = options.outHeight;
        final int width = options.outWidth;
        int size = 1;

        if (height > reqHeight || width > reqWidth)
        {
            if (width > height)
            {
                size = Math.round((float) height / (float) reqHeight);
            }
            else
            {
                size = Math.round((float) width / (float) reqWidth);
            }
        }
        return size;
    }

ListView

Was it helpful?

Solution

The best and easiest way to load images into imageviews is to use a background process to accomplish the task, because blocking the interface will be bad user experience. The are a lot of code samples online, for instance you can use the ImageLoader class from this tutorial. Just add it to your project and use it like:

ImageLoader loader = new ImageLoader(context);
loader.DisplayImage(url, imagview);

EDIT: When you fetch it from the web, you are most probably getting the image as a stream. You could do that, but the most efficient and popular way to deal with images in databases, is to not store the actual image data in the database, because read/write operation are not efficient.

Instead what you could do is, to store the stream you get from the web to a file in some folder, and once you store it, store the path pointing to it in the database where the image should be located. In this way your database is much lighter and you open the image just when you need it. Actually this is the correct way to deal with images because once your image size increase, reading from it won't be possible, since Android limits the cursor window size to 1MB.

So I advice you the modify your code as explained.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top