0

I have implemented lazy loading of images(from remote server) in my application(twitter kind of app) and the fetching part and loading the image into the exact imageView works perfectly fine. But the "getView" part of the adapter gets called only after I scroll down the ListView and so images are fetched from remote server(I fetch images by executing an asyntask inside the adapter "getView" code) only after I scroll down and I can see a considerable amount of delay in the images being loaded. Once the images are loaded and stored in memory cache there is no problem while scrolling up or down. The only problem is images loading for the first time loading slow

So is there a way to rectify it in such a way that by the time I scroll down I should be able to get the image bitmap and the set the bitmap when I scroll down. I want it to be exactly like twitter app where I couldn't see lag in loading profile pictures.

TIA

Jagadeesh
  • 883
  • 1
  • 10
  • 26

3 Answers3

0

Well your approach is incorrect you have to fetch all the images before showing them as get view called every time you scroll the list so every time your service get called and fetch the no. of images that a list can display on screen (say 4-5 at a time).

What you have to do is :- 1) Fetch all images. 2) As you fetch all the images set adapter to listview and you will have all images in your list without any delay as you already have downloaded the images,

But this is not lazy loading -- lazy loading means user got to see only some part of images at a time if he doest not scroll there is no point downloading images from service.

Hope that will be helpful

Jitender Dev
  • 6,907
  • 2
  • 24
  • 35
  • 1
    Thanks for the reply. My app is like a twitter app where I would fetch 10 feeds and keep fetching when the user scrolls down. So I would get the image Urls only during scrolling – Jagadeesh Dec 04 '12 at 06:49
  • if you fetch images part by part you cannot ignore the downloading time of images this is what causing delay in getview. You have to get all images before passing them to adapter. – Jitender Dev Dec 04 '12 at 07:00
  • Not exactly, you could also load position + 10 images and cache them so scrolling down would show these images, while also causing a new webservice call for the images position+10 down the list. Retrieving all images would not be efficient in a lot of cases, like in twitter where the list is almost endless. See my answer. – NickL Dec 04 '12 at 07:11
  • He is already using asyncTask in getView method there is no point starting another back ground process. Moreover the real problem arises when the user scroll to say 11th image and leaves the app but in your approach you are forcing application to load un necessary 9 more images thereby increasing downloading time. – Jitender Dev Dec 04 '12 at 07:21
  • Using an AsyncTask is not the problem, neither is the 'unnecessary loading of images', since in your approach he would have to load ALL images. Even if the app is accidentally clicked. Only way to NOT load all images, but still scroll smooth, is to load enough images ahead to retrieve them before they have to be shown. If the image hasn't been loaded yet, might be due to slow connection, you would have to visualize this with a 'Loading..' dialog or something like that. Again, see my answer. Also, loading could be halted when the user leaves the app. It is all about design. – NickL Dec 04 '12 at 07:32
  • And yes, just loading 10 images ahead, and when scrolling down one position causes loading the next 10 images ahead, would cause serious performance issues. Since the position+9 images would already be 'retrieving'. This would be a design error, or flaw. Yes, loading ALL images at start would be the easiest way, but might not even be possible in all situations. – NickL Dec 04 '12 at 07:38
0

If you call your webservice in the getView() method, it will be called every time you scroll up and down. Since the getView method is called for the rows that are visible on screen.

What you could do, is load the images to a HashMap<int, Object>, where int == position in listview, and object is the image. In the getview you could then check if positions + (1 -> 10) have been loaded, and if not, retrieve them from the webservice in some kind of background task. Load the images in the hashmap, and make the getView() method use those images. Not the images directly retrieved from the webservice. Otherwise, you indeed would have to wait for them to be retrieved. Also this way you cache the images in the hashmap instead of repeatedly retrieving the same ones when scrolling up and down.

Of course there are already people who have made such adapters, just by searching for it here I found this SO question, which has an answer that refers to the CommonsWare endless adapter.

Community
  • 1
  • 1
NickL
  • 4,258
  • 2
  • 21
  • 38
0

There is a library called AALP that you can use to help you with Lazy loading of list views. https://bitbucket.org/zedvoid/aalp/src This could save you some time and effort hopefully.

Rod Burns
  • 2,104
  • 13
  • 24