package czd.lib.view.smartimageview;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import czd.lib.cache.BitmapCache;
import czd.lib.view.progress.ProgressCircle;
import java.io.File;
import java.lang.ref.WeakReference;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class SmartImageView extends FrameLayout {
protected static ExecutorService threadPool = Executors.newFixedThreadPool(3);
protected static Map<Context,List<WeakReference<Future<?>>>> requestMap = new WeakHashMap<Context,List<WeakReference<Future<?>>>>();
protected boolean loading = false;
protected SmartImageTask currentTask;
protected Context context;
protected ImageView imageview;
protected ProgressCircle progress;
protected int width = 0, height = 0;
protected String file;
protected boolean useloading = false;
protected Bitmap imagebitmap;
public SmartImageView(Context context) {
super(context);
this.context = context;
initView();
}
public SmartImageView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
initView();
}
public SmartImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
initView();
}
private void initView() {
imageview = new ImageView(this.context);
imageview.setScaleType(ScaleType.CENTER_CROP);
imageview.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
imageview.setVisibility(View.INVISIBLE);
this.addView(imageview);
progress = new ProgressCircle(context);
progress.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
progress.setVisibility(View.INVISIBLE);
progress.showText(false);
this.addView(progress);
}
// Helpers to set image by URL
public void setImageUrl(String url) {
setImage(new WebImage(url));
}
public void setImageUrl(String url,SmartImageListener completeListener){
setImageUrl(url,true,completeListener);
}
public void setImageUrl(String url, final boolean useloading, SmartImageListener completeListener) {
setImage(new WebImage(url), useloading, completeListener);
}
public void setImageUrl(String url, final boolean useloading, final Integer fallbackResource) {
setImage(new WebImage(url), useloading, fallbackResource);
}
public void setImageUrl(String url, final boolean useloading, final Integer fallbackResource, SmartImageListener completeListener) {
setImage(new WebImage(url), useloading, fallbackResource, completeListener);
}
// Helpers to set image by contact address book id
public void setImageContact(long contactId) {
setImage(new ContactImage(contactId));
}
public void setImageContact(long contactId, final Integer fallbackResource) {
setImage(new ContactImage(contactId), false, fallbackResource);
}
public void setImageContact(long contactId, final Integer fallbackResource, final Integer loadingResource) {
setImage(new ContactImage(contactId), false, fallbackResource);
}
public void setImageResource(int resId) {
imageview.setImageResource(resId);
imageview.setVisibility(View.VISIBLE);
}
public void setImageDrawable(Drawable drawable) {
imageview.setImageDrawable(drawable);
imageview.setVisibility(View.VISIBLE);
}
// Set image using SmartImage object
public void setImage(final SmartImage image) {
setImage(image, false, null, null);
}
public void setImage(final SmartImage image, final boolean useloading, final SmartImageListener completeListener) {
setImage(image, useloading, null, completeListener);
}
public void setImage(final SmartImage image, final boolean useloading, final Integer fallbackResource) {
setImage(image, useloading, fallbackResource, null);
}
public void setImage(final SmartImage image, final boolean useloading, final Integer fallbackResource, final SmartImageListener completeListener) {
if ((imagebitmap == null || imagebitmap.isRecycled()) && !loading)
{
loading = true;
this.useloading = useloading;
currentTask = new SmartImageTask(context, image, new SmartImageTask.OnCompleteHandler() {
@Override
public void onStart() {
super.onStart();
if (loading)
{
if (useloading)
progress.setVisibility(View.VISIBLE);
if (completeListener != null)
completeListener.onStart();
}
}
@Override
public void onFailure() {
super.onFailure();
if (loading)
{
loading = false;
if (useloading)
progress.setVisibility(View.INVISIBLE);
if (fallbackResource != null)
{
imageview.setAdjustViewBounds(false);
imageview.setImageResource(fallbackResource);
imageview.setVisibility(View.VISIBLE);
}
if (completeListener != null)
completeListener.onFailure();
}
}
@Override
public void onSuccess(Bitmap bitmap) {
super.onSuccess(bitmap);
if (loading)
{
loading = false;
if (useloading)
progress.setVisibility(View.INVISIBLE);
file = BitmapCache.getInstance().getRealName(image.toString());
imagebitmap = bitmap;
width = imagebitmap.getWidth();
height = imagebitmap.getHeight();
imageview.setAdjustViewBounds(false);
imageview.setImageBitmap(imagebitmap);
imageview.setVisibility(View.VISIBLE);
if (completeListener != null)
completeListener.onSuccess();
}
}
@Override
public void onProgress(long current, long total) {
super.onProgress(current, total);
if (loading)
{
progress.setMax(total);
progress.setProgress(current);
if (completeListener != null)
completeListener.onProgress(current, total);
}
}
});
Future<?> request = threadPool.submit(currentTask);
if (request != null && context != null)
{
List<WeakReference<Future<?>>> requestList = requestMap.get(context);
if (requestList == null)
{
requestList = new LinkedList<WeakReference<Future<?>>>();
requestMap.put(context, requestList);
}
requestList.add(new WeakReference<Future<?>>(request));
}
}
}
public int[] getImageSize() {
return new int[]{width, height};
}
public File getBitmapFile() {
return new File(file);
}
public void recycle() {
if (currentTask != null)
currentTask.cancel();
if (loading)
{
loading = false;
if (useloading)
progress.setVisibility(View.INVISIBLE);
}
imageview.setVisibility(View.INVISIBLE);
if (imagebitmap != null && !imagebitmap.isRecycled())
{
imagebitmap.recycle();
}
imagebitmap = null;
width = 0;
height = 0;
}
public void cancel() {
recycle();
}
public static void cancelTasks(Context context, boolean mayInterruptIfRunning) {
List<WeakReference<Future<?>>> requestList = requestMap.get(context);
if (requestList != null)
{
for (WeakReference<Future<?>> requestRef : requestList)
{
Future<?> request = requestRef.get();
if (request != null && !request.isCancelled())
{
request.cancel(mayInterruptIfRunning);
}
}
}
requestMap.remove(context);
}
public static void cancelAllTasks(boolean mayInterruptIfRunning) {
for (List<WeakReference<Future<?>>> requestList : requestMap.values())
{
if (requestList != null)
{
for (WeakReference<Future<?>> requestRef : requestList)
{
Future<?> request = requestRef.get();
if (request != null && !request.isCancelled())
{
request.cancel(mayInterruptIfRunning);
}
}
}
}
requestMap.clear();
//threadPool.shutdownNow();
//threadPool = Executors.newFixedThreadPool(3);
}
}