As an Android consultant, I find myself needing to load remote images into an ImageView quite often. Doing this with the Picasso library is quite easy as you simply need to tell the library where the image is located and what ImageView to load the image into. At that point everything else is taken care of for you, including caching (thanks Square Engineering team!) This is great! The code to do this looks like this:
However, I have a problem with this approach. As time progresses you’ll have various different Picasso instantiations all over your code base when you need to load up a new image. This can be easily solved with the Dagger Dependency Injection container and a custom ImageView that I call UrlImageView. This file is shown below:
The UrlImageView.java file is simply an ImageView that has been extended to add a couple of additional methods. The method that we care about in this example is setUrl(). When this method is called, a url is passed into the class and then the injected Picasso instance loads that image located at that URL into into the ImageView (this). During the load, a placeholder is shown. This is the defaultImageId that is a private variable. The placeholder is a drawable file that you use.
Once the file is downloaded, its cached, etc. This depends on how you’ve configured the injected instance of Picasso.
To use this class, simply find the view in your Activity and call setUrl() it as shown below. Everything else is handled for you.
So how did I inject Picasso? Easy. With a simple @Provides annotation in our Dagger module as shown below.
Dagger will create the Picasso instance here and each place that I @Inject Picasso this same set up will be used. This has some benefits. Using Dagger I can create different Picasso instances with the @Named attribute (or by extending Picasso). An example of this would be a simple image loader as we’ve done above. The second example would allow me to create a RoundPicasso provider that renders circle images (think Google+ avatars). You would set up Picasso the same as before but you would also call the transform() method and provide a custom implementation of the Transformation interface that renders the image as a circle.
As you can see, its easy to extend an ImageView with very little code to load remote images. I hope this has helped you develop Android applications faster and more effectively.