Sunday, 29 April 2012

Crossfading images in a ListView

ListViews that contain images populated from a server are used a lot. Adding a nice crossfade animation when the images load can really help add some polish to your app. In this scenario the ListView shows a default image and once the required image is downloaded it then displays the downloaded image. Below shows two screenshots of the TED app one showing a ListView with default images, and the other showing the ListView once the images have been downloaded.


The TED app is an example of a really nice android app and it works great. But if you try it, and watch closely as the listview populates the images, you’ll notice that once each image is loaded the default TED image disappears and the downloaded images appears. There’s no transition, one disappears and the other appears. This is ok but does create a slightly jarring experience, in the real world we’re not accustomed to things just appearing and disappearing.

To help create a better experience what we can do is create a transition between the two images. In this case a crossfade transition would work well. Gradually fading the default image out and downloaded image in. Here’s a video showing an example App’ that I created with this crossfade transition.


This video shows an example app that I wrote to test the crossfade transition on the images in a  ListView. It’s a simple app that just downloads images from a Picasa JSON feed. Hopefully you’ll agree that the crossfade of the images is a nice addition and really adds to the user experience.

To do this I first looked at the TransitionDrawable in the Android libs. This looked like a good candidate as it allows two drawables to be associated with it  that you can then crossfade between. Unfortunately this class didn’t quite work for the scenario of transitioning in Listviews as it assumes that you have both drawables when the TransitionDrawable is created. Obviously in this scenario we don’t have both drawables until the second drawable has been downloaded from the server.  

So with a little more searching I then found a class called CrossFadeDrawable that is part of the Shelves app created by Romain Guy. This class is in fact very similar to TransistionDrawble but it also has methods that allow the setting of the end (downloaded) drawable, so it doesn’t need to have both drawables defined up front. The CrossFadeDrawble was almost exactly what I needed , but there was still one more thing that needed to be fixed.

The original CrossfadeDrawble assumed that the start Image (default image) and the end image(downloaed image) would be of the same dimensions. This was not the case in my scenario. What I wanted was something that would scale the downloaded image to fit inside the default start image.


The last thing to do was to add a tweak to the CrossfadeDrawable so that it would use a matrix transformation to scale the downloaded image until it would fit into the dimensions of the default (start) image.

So that was all that needed to be done to create the crossfade transition. Of course since we are using a list view we still have to create an Adapter to populate the list and an Async task to download the images and update the CrossfadeDrawable.


2 comments:

  1. Hey :) thanks for the article;

    Any link to a github repo / code sample ?

    ReplyDelete
  2. Awesome! but any way to access the source code to this or some sort of demo application would help.

    Thanks

    ReplyDelete