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.
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.
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.
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.
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.
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, …
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.)
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.)
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(); } }
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With