Android Volley - how to animate image loading?

urSus picture urSus · May 27, 2013 · Viewed 14.4k times · Source

any idea how to play a fade in animation when image loads? Now it just blinks into place. I am using NetworkImageView from the Volley toolkit.

Also, is there a way to set loading and error bitmaps on the network image view without using the ImageLoader.get( .. ) ?

Thanks!

//EDIT: Okay, thanks to you all, but if we want to be perfectionists, we should only animate if loading from disk cache, overriding setImageBitmap would case animation to go off even if pulled from memcache

what you want to do is add a boolean shouldAnimate to ImageListener.onResponse like this

public static ImageListener getImageListener(final ImageView view, final int defaultImageResId,
        final int errorImageResId) {
    return new ImageListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            if (errorImageResId != 0) {
                view.setImageResource(errorImageResId);
            }
        }

        @Override
        public void onResponse(ImageContainer response, boolean isImmediate, boolean shouldAnimate) {
            if (response.getBitmap() != null) {
                if (shouldAnimate) {
                    // ADDED
                    view.setAlpha(0f);
                    view.setImageBitmap(response.getBitmap());
                    view.animate().alpha(1f).setDuration(1000);
                    // END ADDED
                } else {
                    view.setImageBitmap(response.getBitmap());
                }
            } else if (defaultImageResId != 0) {
                view.setImageResource(defaultImageResId);
            }
        }
    };
}

this is a method that sets the bitmap, no matter where it is from, so you need to set it to false to every usage in ImageLoader except for

class BatchedImageRequest {

   private void batchResponse(String cacheKey, BatchedImageRequest request,
        final VolleyError error) {
      ...
      container.mListener.onResponse(container, false, true);
      ...
   }
}

I've created a Gist for Copy & Paste usage - https://gist.github.com/ursusursus/5732521

Answer

benvd picture benvd · Jun 5, 2013

Example implementation of CommonsWare's answer can be found here: https://gist.github.com/benvd/5683818.

Using a TransitionDrawable does add an extra layer of overdraw. If you want to avoid that, perhaps using a ViewPropertyAnimator might help.

The gist of it is basically to have the following snippet in your setImageBitmap():

TransitionDrawable td = new TransitionDrawable(new Drawable[]{
        new ColorDrawable(android.R.color.transparent),
        new BitmapDrawable(getContext().getResources(), bm)
});

setImageDrawable(td);
td.startTransition(FADE_IN_TIME_MS);