views:

95

answers:

1

Hi,

I've reviewed some posts about lazy loading but I believe my problem is a bit different.

I have a gallery (my class extends Gallery) which displays 20 rather large in size images (400-500K each). I cannot load them all to gallery since I get an OutOfMemory exception.
So, I created an array of 20 Drawables and initially populated the first 9 elements (the images come from the Web) and set all the rest to null. My intention was this: on a fling to the right, fetch element no. 10 and set to null element no. 0. On another fling to the right fetch element no. 11 and set to null element no. 1 to null. Same logic on a fling left.

The problem is I can fling much faster than the elements are fetched. My gallery has a BaseAdapter and its getView() looks something like this:

public View getView(int position, View  convertView, ViewGroup  parent){
     ImageView imageView = new ImageView();
     imageView.setDrawable(imageArray[position];
     ....
     ....

     return imageView;
}

How do I tell getView() - if imageArray[position] is still null, show a "loading..." dialog and once it is set repeat yourself with the same position?
I don't want to see the imageView empty and then set on the fly. I want to not be able to see the imageView at all until it is set.

Thanks.

A: 

Gallery is designed for smooth experience. It will be very bad UI if you block the screen and don't switch to next image until it is fetched. This way user will not be able to fling at all. You should display some loading indicator instead of image while it is loading.

I think your scenario is rather common. You should download images and display them. If you get OutOfMemory you can try to supersample images http://stackoverflow.com/questions/477572/android-strange-out-of-memory-issue/823966#823966.

If there's still OutOfMemory you should remove bitmaps from memory and cache them to SD. So when user flings back you can load images from SD again, it will be fast enough. And memory consumption will be lower. As you suggest you can have 10 most recent images cached in memory and others cached on SD.

You can take a look at my sample code http://stackoverflow.com/questions/541966/android-how-do-i-do-a-lazy-load-of-images-in-listview/3068012#3068012. Actually it's a ListView adapter but you can apply it to gallery with minor modifications. I think it will do exactly what you need.

Fedor
Thanks Fedor. Will try...
Rob
"You should display some loading indicator instead of image while it is loading."How do I achieve this? I know how to put a loading indicator in a ProgressDialog in front of the gallery, but how do I put the indicator instead of the image itself? Just to remind you, the imageView is created at runtime. If it was defined in XML I could have assigned it a default source but this isn't the case here... thanks.
Rob
It's not a problem. You can create ProgressControl at runtime instead of ImageView. Or you can create ImageView at runtime and display some stub image while real image is being downloaded. I display stub image in my sample code.
Fedor