/** ** Copyright (c) 2010 Ushahidi Inc ** All rights reserved ** Contact: team@ushahidi.com ** Website: http://www.ushahidi.com ** ** GNU Lesser General Public License Usage ** This file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: http://www.gnu.org/licenses/lgpl.html. ** ** ** If you have questions regarding the use of this file, please contact ** Ushahidi developers at team@ushahidi.com. ** **/ package com.ushahidi.android.app.util; import java.lang.ref.WeakReference; import com.ushahidi.android.app.BuildConfig; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.TransitionDrawable; import android.os.AsyncTask; import android.util.Log; import android.widget.ImageView; public class ImageViewWorker { private static final int FADE_IN_TIME = 200; private Context context; private Bitmap loadingBitmap; private boolean fadeIn = true; private static String TAG = ImageViewWorker.class.getSimpleName(); public ImageViewWorker(Context context) { this.context = context; } public void loadImage(Object data, ImageView imageView, boolean fullScale, int width) { final BitmapWorkerTask task = new BitmapWorkerTask(imageView); final AsyncDrawable asyncDrawable = new AsyncDrawable( context.getResources(), loadingBitmap, task); imageView.setImageDrawable(asyncDrawable); task.fullScale = fullScale; task.width = width; task.execute(data); } public void setLoadingImage(Bitmap bitmap) { this.loadingBitmap = bitmap; } public void setImageFadeIn(boolean fadeIn) { this.fadeIn = fadeIn; } public static void cancelWork(ImageView imageView) { final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); if (bitmapWorkerTask != null) { bitmapWorkerTask.cancel(true); if (BuildConfig.DEBUG) { final Object bitmapData = bitmapWorkerTask.data; Log.d(TAG, "cancelWork - cancelled work for " + bitmapData); } } } public static boolean cancelPotentialWork(Object data, ImageView imageView) { final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); if (bitmapWorkerTask != null) { final Object bitmapData = bitmapWorkerTask.data; if (bitmapData == null || !bitmapData.equals(data)) { bitmapWorkerTask.cancel(true); if (BuildConfig.DEBUG) { Log.d(TAG, "cancelPotentialWork - cancelled work for " + data); } } else { // The same work is already in progress. return false; } } return true; } private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) { if (imageView != null) { final Drawable drawable = imageView.getDrawable(); if (drawable instanceof AsyncDrawable) { final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable; return asyncDrawable.getBitmapWorkerTask(); } } return null; } static class AsyncDrawable extends BitmapDrawable { private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference; public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) { super(res, bitmap); bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>( bitmapWorkerTask); } public BitmapWorkerTask getBitmapWorkerTask() { return bitmapWorkerTaskReference.get(); } } private class BitmapWorkerTask extends AsyncTask<Object, Void, Bitmap> { private Object data; private final WeakReference<ImageView> imageViewReference; protected int width; protected boolean fullScale = false; public BitmapWorkerTask(ImageView imageView) { imageViewReference = new WeakReference<ImageView>(imageView); } /** * Background processing. */ @Override protected Bitmap doInBackground(Object... params) { data = params[0]; final String dataString = String.valueOf(data); Bitmap bitmap = null; if (bitmap == null && !isCancelled() && getAttachedImageView() != null) { if ((fullScale) && (width == 0)) { bitmap = ImageManager.getBitmaps(context, dataString); } else { bitmap = ImageManager .getBitmaps(context, dataString, width); } } return bitmap; } /** * Once the image is processed, associates it to the imageView */ @Override protected void onPostExecute(Bitmap bitmap) { // if cancel was called on this task or the "exit early" flag is set // then we're done if (isCancelled()) { bitmap = null; } final ImageView imageView = getAttachedImageView(); if (bitmap != null && imageView != null) { setImageBitmap(imageView, bitmap); } } private ImageView getAttachedImageView() { final ImageView imageView = imageViewReference.get(); final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); if (this == bitmapWorkerTask) { return imageView; } return null; } } /** * Called when the processing is complete and the final bitmap should be set * on the ImageView. * * @param imageView * @param bitmap */ @SuppressWarnings("deprecation") private void setImageBitmap(ImageView imageView, Bitmap bitmap) { if (fadeIn) { // Transition drawable with a transparent drwabale and the final // bitmap final TransitionDrawable td = new TransitionDrawable( new Drawable[] { new ColorDrawable(android.R.color.transparent), new BitmapDrawable(context.getResources(), bitmap) }); // Set background to loading bitmap imageView.setBackgroundDrawable(new BitmapDrawable(context .getResources(), loadingBitmap)); imageView.setImageDrawable(td); td.startTransition(FADE_IN_TIME); } else { imageView.setImageBitmap(bitmap); } } }