/**
** 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);
}
}
}