package com.afollestad.silk.views.image;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import com.afollestad.silk.images.Dimension;
import com.afollestad.silk.images.SilkImageManager;
public class SilkImageView extends ImageView {
private String source;
private SilkImageManager aimage;
protected boolean invalidateOnLoad;
private boolean fitView = true;
protected String lastSource;
private View loadingView;
private boolean mCacheEnabled = true;
public SilkImageView(Context context) {
super(context);
}
public SilkImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SilkImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
protected final void log(String message) {
if (aimage != null && !aimage.isDebugEnabled()) return;
Log.d("SilkImageView", message);
}
@Override
protected final void onSizeChanged(int w, int h, int oldw, int oldh) {
/**
* This method allows the view to wait until it has been measured (a view won't be measured until
* right before it becomes visible, which is usually after your code first starts executing. This
* insures that correct dimensions will be used for the image loading size to optimize memory.
*/
super.onSizeChanged(w, h, oldw, oldh);
loadFromSource();
}
public void setImageURL(SilkImageManager manager, String url, boolean cache) {
if (manager == null)
throw new IllegalArgumentException("The SilkImageManager cannot be null.");
this.aimage = manager;
this.source = url;
this.mCacheEnabled = cache;
loadFromSource();
}
public final void setImageURL(SilkImageManager manager, String url) {
setImageURL(manager, url, true);
}
/**
* Turned on by default as it prevents OutOfMemoryExceptions. Sets whether or not the loaded image will be
* resized to fit the dimensions of the view.
*/
public SilkImageView setFitView(boolean fitView) {
this.fitView = fitView;
return this;
}
/**
* Sets the view that will become visible when the view begins loading an image, and will be hidden when the
* view finishes loading an image. The imageview itself will also be hidden during loading if a loading view is set.
*/
public final SilkImageView setLoadingView(View view) {
this.loadingView = view;
return this;
}
protected Bitmap onPostProcess(Bitmap image) {
return image;
}
/**
* Loads the fallback image set from the {@link com.afollestad.silk.images.SilkImageManager} set via #setManager.
*/
public final void showFallback(SilkImageManager manager) {
aimage = manager;
if (aimage == null)
throw new IllegalStateException("You cannot load the fallback image until you have set a SilkImageManager via setManager().");
log("Loading fallback image for view...");
aimage.get(SilkImageManager.SOURCE_FALLBACK, new SilkImageManager.AdvancedImageListener() {
@Override
public void onImageReceived(final String source, final Bitmap bitmap) {
setImageBitmap(bitmap);
if (invalidateOnLoad) {
requestLayout();
invalidate();
}
log("Fallback image set to view.");
}
@Override
public Bitmap onPostProcess(Bitmap image) {
return SilkImageView.this.onPostProcess(image);
}
}, new Dimension(this));
}
private void loadFromSource() {
if (aimage == null) {
return;
} else if (source == null || source.trim().isEmpty()) {
showFallback(aimage);
return;
} else if (getMeasuredWidth() == 0 && getMeasuredHeight() == 0) {
log("View not measured yet, waiting...");
return;
}
lastSource = source;
final Dimension dimen = this.fitView ? new Dimension(this) : null;
if (loadingView != null) {
loadingView.setVisibility(View.VISIBLE);
this.setVisibility(View.GONE);
}
aimage.get(this.source, new SilkImageManager.AdvancedImageListener() {
@Override
public void onImageReceived(final String source, final Bitmap bitmap) {
if (lastSource != null && !lastSource.equals(source)) {
log("View source changed since download started, not setting " + source + " to view.");
return;
}
// Post on the view's UI thread to be 100% sure we're on the right thread
SilkImageView.this.post(new Runnable() {
@Override
public void run() {
setImageBitmap(bitmap);
if (invalidateOnLoad) {
requestLayout();
invalidate();
}
if (loadingView != null) {
loadingView.setVisibility(View.GONE);
SilkImageView.this.setVisibility(View.VISIBLE);
}
log(source + " set to view " + SilkImageManager.Utils.getKey(source, dimen));
}
});
}
@Override
public Bitmap onPostProcess(Bitmap image) {
return SilkImageView.this.onPostProcess(image);
}
}, dimen, mCacheEnabled);
}
}