How to Lazy Load Images in ListView in Android

How to Lazy Load Images in ListView in Android

22 May 2024 Stephan Petzl Leave a comment Tech-Help

When developing Android applications, efficiently loading images in a ListView can significantly enhance the user experience. This article provides a comprehensive guide on how to implement lazy loading to ensure that while text displays immediately, images load progressively without blocking the UI.

Introduction

Lazy loading is a design pattern commonly used in computer programming to defer initialization of an object until the point at which it is needed. In the context of Android development, lazy loading images in a ListView ensures that images are loaded asynchronously, preventing the UI from freezing while images are fetched from the Internet.

Basic Implementation

A straightforward way to implement lazy loading is by using a custom DrawableManager class. This class manages the fetching and caching of images.

DrawableManager Class

package com.example.app;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;

import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.widget.ImageView;

import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.HttpResponse;

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);
        }

        try {
            InputStream is = fetch(urlString);
            Drawable drawable = Drawable.createFromStream(is, "src");
            if (drawable != null) {
                drawableMap.put(urlString, drawable);
            }
            return drawable;
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            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(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message message) {
                imageView.setImageDrawable((Drawable) message.obj);
            }
        };

        Thread thread = new Thread() {
            @Override
            public void run() {
                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();
    }
}

  

Advanced Solutions

While the above implementation is a good starting point, there are more advanced libraries available that handle lazy loading of images more efficiently and with additional features. Here are some popular libraries:

  • Picasso: A powerful image downloading and caching library for Android. It handles image view recycling, download cancellation, and automatic memory and disk caching.
    Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
  • Glide: A fast and efficient image loading library for Android. It supports fetching, decoding, and displaying images, as well as animated GIFs.
    Glide.with(this).load("your-url-here").into(imageView);
  • Fresco: A powerful system for displaying images in Android applications. It provides two levels of cache, one in memory and another in internal storage.

Conclusion

Implementing lazy loading for images in a ListView can greatly improve the performance and user experience of your Android application. By using advanced libraries like Picasso, Glide, or Fresco, you can ensure efficient image loading and caching, reducing the risk of UI freezes and out-of-memory errors.

Enhance Your Testing with Repeato

As you optimize your app’s performance with efficient image loading, consider enhancing your testing process with Repeato. Repeato is a no-code test automation tool for iOS and Android, helping you create, run, and maintain automated tests swiftly. With features like computer vision and AI, Repeato allows mobile developers to focus on building great products while delegating test automation to non-technical colleagues or QAs. For more information, check our documentation.

Like this article? there’s more where that came from!