Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to lazy load images in ListView in Android

I am using a ListView to display some images and captions associated with those images. I am getting the images from the Internet. Is there a way to lazy load images so while the text displays, the UI is not blocked and images are displayed as they are downloaded?

The total number of images is not fixed.

like image 552
lostInTransit Avatar asked Feb 12 '09 15:02

lostInTransit


People also ask

How lazy loading works in Android?

Lazy image loading means delegating image loading tasks to a ready-made program. You don't need to write the entire code. Once you set up the library, it'll take care of the process for you by initiating an asynchronous load/download process.

What is lazy loading in java?

The concept of delaying the loading of an object until one needs it is known as lazy loading. In other words, it is the process of delaying the process of instantiating the class until required.

How is lazy loading achieved when is it useful what are its pitfalls?

One form of lazy loading is infinity scroll, in which, the content of the web page is loaded as and when the user scrolls down the page. It is a popular technique being used by various websites. Advantages of Lazy loading: On-demand loading reduces time consumption and memory usage thereby optimizing content delivery.

How to lazy load images from web to listview?

Using lazy loading to download images in a listview. Using custom adapter to create lisview rows and using ImageLoader class to lazy load images from web and show in listview row.

How do I lazy load an image in Android?

In android, there are many library to lazy load image like glide/picasso/universal image loader. All of theme has many features to help you make an better application like lazy loading, disk cache, ram cache, image crop, …

What is the best library for lazy loading images?

AQuery is one such library, but it is better than most of them in all aspects and is worth trying for. You must try this Universal Loader is best. I am using this after done many RnD on lazy loading . Wide customization of ImageLoader's configuration (thread executors, downloader, decoder, memory and disk cache, display image options, etc.)

What are the customization options of imageloader?

Wide customization of ImageLoader's configuration (thread executors, downloader, decoder, memory and disk cache, display image options, etc.) Many customization options for every display image call (stub images, caching switch, decoding options, Bitmap processing and displaying, etc.)


2 Answers

Here's what I created to hold the images that my app is currently displaying. Please note that the "Log" object in use here is my custom wrapper around the final Log class inside Android.

package com.wilson.android.library;  /*  Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.  You may obtain a copy of the License at  http://www.apache.org/licenses/LICENSE-2.0  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the specific language governing permissions and limitations under the License. */ import java.io.IOException;  public class DrawableManager {     private final Map<String, Drawable> drawableMap;      public DrawableManager() {         drawableMap = new HashMap<String, Drawable>();     }      public Drawable fetchDrawable(String urlString) {         if (drawableMap.containsKey(urlString)) {             return drawableMap.get(urlString);         }          Log.d(this.getClass().getSimpleName(), "image url:" + urlString);         try {             InputStream is = fetch(urlString);             Drawable drawable = Drawable.createFromStream(is, "src");               if (drawable != null) {                 drawableMap.put(urlString, drawable);                 Log.d(this.getClass().getSimpleName(), "got a thumbnail drawable: " + drawable.getBounds() + ", "                         + drawable.getIntrinsicHeight() + "," + drawable.getIntrinsicWidth() + ", "                         + drawable.getMinimumHeight() + "," + drawable.getMinimumWidth());             } else {               Log.w(this.getClass().getSimpleName(), "could not get thumbnail");             }              return drawable;         } catch (MalformedURLException e) {             Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);             return null;         } catch (IOException e) {             Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);             return null;         }     }      public void fetchDrawableOnThread(final String urlString, final ImageView imageView) {         if (drawableMap.containsKey(urlString)) {             imageView.setImageDrawable(drawableMap.get(urlString));         }          final Handler handler = new Handler() {             @Override             public void handleMessage(Message message) {                 imageView.setImageDrawable((Drawable) message.obj);             }         };          Thread thread = new Thread() {             @Override             public void run() {                 //TODO : set imageView to a "pending" image                 Drawable drawable = fetchDrawable(urlString);                 Message message = handler.obtainMessage(1, drawable);                 handler.sendMessage(message);             }         };         thread.start();     }      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();     } } 
like image 79
James A Wilson Avatar answered Sep 29 '22 07:09

James A Wilson


I made a simple demo of a lazy list (located at GitHub) with images.

Basic Usage

ImageLoader imageLoader=new ImageLoader(context); ... imageLoader.DisplayImage(url, imageView);  

Don't forget to add the following permissions to your AndroidManifest.xml:

 <uses-permission android:name="android.permission.INTERNET"/>  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> Please 

create only one instance of ImageLoader and reuse it all around your application. This way image caching will be much more efficient.

It may be helpful to somebody. It downloads images in the background thread. Images are being cached on an SD card and in memory. The cache implementation is very simple and is just enough for the demo. I decode images with inSampleSize to reduce memory consumption. I also try to handle recycled views correctly.

Alt text

like image 39
Fedor Avatar answered Sep 29 '22 07:09

Fedor