0

I want to implement a lazy loading image in my ListView. At first I need to connect to a url and get the urlStrings for all images which belong to an object. I get a jsonString and then parse:

String RESTUrl = new MasterdataDataProvider(mContext).getSyncServicePath() + "PhotoInfo/" + objectEntryID; 
List<String> urlStrings = new ArrayList<String>();
try {
    HttpGet httpGet = new HttpGet((RESTUrl + "/" + token));
    HttpParams httpParameters = new BasicHttpParams();
    DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
    httpGet.addHeader("Accept", "application/json");
    httpGet.addHeader("Content-Type", "application/json");
    HttpResponse response = httpClient.execute(httpGet);
    String jsonData = EntityUtils.toString(response.getEntity());
    if (!jsonData.equals("[]")) {
        GsonPhotoInfo x = new GsonPhotoInfo(new GsonBuilder());
        PhotoInfo[] info = x.parseJSON(jsonData);
        for(PhotoInfo p : info) {
            System.out.println(p.getFileName());
            urlStrings.add(photoWebURL + objectDefID + "/" + objectEntryID + "/" + p.getFileName());
        }

   }
} catch(Exception e) {
        e.printStackTrace();
}

As you see in this piece of code I fetch the FileName from jsonData.

Then I need to download the images from urlStrings:

final Handler handler = new Handler() {
     @Override
     public void handleMessage(Message message) {
          ImagePagerAdapter adapter = new ImagePagerAdapter((Drawable[]) message.obj);
          viewPager.setAdapter(adapter); 
     }
};

     Thread thread = new Thread() {
     @Override
     public void run() {

         //PARSE THE JSON DATA and FETCH URLStrings (as you see in the piece of code at top)                       

         Drawable[] drawables = new Drawable[urlStrings.size()];
         for(int i=0; i< urlStrings.size(); i++) 
               drawables[i] = fetchDrawable(urlStrings.get(i));

               Message message = handler.obtainMessage(1, drawables);
               handler.sendMessage(message);
         }
    };
    thread.start();  

The code to fetch image is taken from James Wilson answer.

So as you can see there as well, I have to use HTTPClient once again to download every image:

private InputStream fetch(String urlString) throws MalformedURLException, IOException {
    DefaultHttpClient httpClient = new DefaultHttpClient();
    HttpGet request = new HttpGet(urlString);
    HttpResponse response = httpClient.execute(request);
    return response.getEntity().getContent();
}

The problem is it is not working in my listView. The images are not loaded correctly in listView sometimes, and I am just wondering that is it because of the way that :

  1. I get the urlStrings from jsonData, and then
  2. Download the images from urlStrings one by one.

I mean I connect to REST two times. I am also using a Handler that maybe is not a good option, but actually I tested it with a AsyncTask and I had the same problem.

I appreciate for any idea that could solve my problem.

Addenda:

I found out images are loaded incorrectly when I scroll in the list very fast, otherwise it is fine.

Community
  • 1
  • 1
Ali
  • 9,800
  • 19
  • 72
  • 152

3 Answers3

0

Use UniversalImageLoader library from here. It pretty much works error free. Does memory handling, threading and all other stuff.

Takes 2 minutes to integrate. Try it out !

Gaurav Arora
  • 17,124
  • 5
  • 33
  • 44
  • Good to know that, but I am basically want to find the reason that where the problem come from in my code. – Ali Apr 19 '13 at 08:13
  • Can you share your ImagePagerAdapter code. Things look fine here ! – Gaurav Arora Apr 19 '13 at 08:24
  • https://github.com/chiuki/android-swipe-image-viewer/blob/master/src/com/sqisland/android/swipe_image_viewer/MainActivity.java – Ali Apr 19 '13 at 08:36
  • The problem is in your `ImagePagerAdapter` since adapters control how view will be displayed on screen. On fast scrolling, the adapters might not be instanting the right element thereby giving an incorrect element. Try reviewing `instantiateItem()` method in `ImagePagerAdapter` – Gaurav Arora Apr 19 '13 at 09:59
0

Oh boy!! you are setting the list adapter every time you download an image. I would suggest you to go with androids tutorial for using a list view and then listview with lazy image loading.

List view

http://developer.android.com/training/improving-layouts/smooth-scrolling.html

Image handling

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

jaga
  • 753
  • 11
  • 18
  • Where in the code? Setting the viewPage adapter is different from ListView adapter. right? – Ali Apr 19 '13 at 08:21
  • Can you make it bit more clear? Where do u use the ImagePagerAdapter? – jaga Apr 19 '13 at 08:35
  • https://github.com/chiuki/android-swipe-image-viewer/blob/master/src/com/sqisland/android/swipe_image_viewer/MainActivity.java – Ali Apr 19 '13 at 08:51
  • Ok. So you are using a ViewPager to display a list of images? If yes, then still my response is valid. You are creating and setting adapter to the viewpager after every image is loaded. – jaga Apr 19 '13 at 08:57
  • I am using `Thread`. So the adapter will be set after images are downloaded. Please share some code if you have a better aprroach. (As I said in the question every object can have couple of images.) – Ali Apr 19 '13 at 09:20
0

I solved my problem by implementing OnScrollListener for my ListView, and download the image when scroll is in idle mode. But I think the right way is not get the image url in the lazy loading implementation, Maybe the image url need to be included in the main Object.

public static boolean scroll_is_idle = true;

mListView.setOnScrollListener(new OnScrollListener() {
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { }

    public void onScrollStateChanged(AbsListView view, int scrollState) {
        switch (scrollState) {
                case OnScrollListener.SCROLL_STATE_IDLE:
                    scroll_is_idle = true;
                    mAdapter.notifyDataSetChanged();
                    break;
                case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL: 
                    scroll_is_idle = false;
                    break;
                case OnScrollListener.SCROLL_STATE_FLING:
                    scroll_is_idle = false;
                    break;
        }
    }
});
Ali
  • 9,800
  • 19
  • 72
  • 152