-
-
Save dlew/69e6557604926d7e1513 to your computer and use it in GitHub Desktop.
This is a simple version of UrlBitmapDrawable, an Android Drawable that can automatically reload a URL from an image library.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This is a version of BitmapDrawable that's associated with a particular URL. | |
* It automatically caches and reloads itself as its Bitmap is flushed from memory. | |
* | |
* When using this with an ImageView, use loadImageView(), as there is some special | |
* handling needed when using ImageViews. | |
*/ | |
public class UrlBitmapDrawable extends BitmapDrawable { | |
private String mUrl; | |
private Bitmap mDefaultBitmap; | |
private WeakReference<ImageView> mImageView; | |
private boolean mRetrieving; | |
private boolean mFailed; | |
public UrlBitmapDrawable(Resources resources, String url, Bitmap defaultBitmap) { | |
super(resources, defaultBitmap); | |
mUrl = url; | |
mDefaultBitmap = defaultBitmap; | |
// Start loading immediately | |
retrieveImage(false); | |
} | |
/* | |
* We need to do perform a hack to work properly with ImageViews, | |
* so most of the time you will be using this method. | |
*/ | |
public static UrlBitmapDrawable loadImageView(String url, ImageView imageView, Bitmap defaultBitmap) { | |
UrlBitmapDrawable drawable = new UrlBitmapDrawable(imageView.getContext().getResources(), url, defaultBitmap); | |
// If there's already a UrlBitmapDrawable associated with this ImageView, | |
// disassociate it (so we don't have two UrlBitmapDrawables trying to | |
// operate on the same ImageView). | |
Drawable currDrawable = imageView.getDrawable(); | |
if (currDrawable instanceof UrlBitmapDrawable) { | |
((UrlBitmapDrawable) currDrawable).mImageView = null; | |
} | |
imageView.setImageDrawable(drawable); | |
drawable.mImageView = new WeakReference<ImageView>(imageView); | |
return drawable; | |
} | |
@Override | |
public void draw(Canvas canvas) { | |
// If URL not set, or we could not retrieve the image for this drawable, don't draw (or draw default) | |
if (mFailed) { | |
if (mDefaultBitmap != null) { | |
super.draw(canvas); | |
} | |
return; | |
} | |
// If URL not loaded (either being null or recycled), load it now (and fallback to default) | |
Bitmap bitmap = getBitmap(); | |
if (bitmap == null || bitmap.isRecycled()) { | |
if (mDefaultBitmap != null) { | |
setBitmap(mDefaultBitmap); | |
} | |
retrieveImage(false); | |
} | |
else { | |
super.draw(canvas); | |
} | |
} | |
private void retrieveImage(boolean forceRetrieve) { | |
if (!mRetrieving || forceRetrieve) { | |
mRetrieving = true; | |
MyImageLib.loadImage(mUrl, mCallbacks); | |
} | |
} | |
private MyImageCallbacks mCallbacks = new MyImageCallbacks() { | |
@Override | |
public void onLoad(Bitmap bitmap) { | |
if (bitmap != null) { | |
setBitmap(bitmap); | |
// This is a hack to get the ImageView to re-measure the | |
// width/height of this Drawable without having to completely | |
// re-implement ImageView. Without a re-measure this drawable | |
// can end up skewed in the ImageView. | |
if (mImageView != null) { | |
final ImageView imageView = mImageView.get(); | |
if (imageView != null) { | |
imageView.setImageDrawable(null); | |
imageView.setImageDrawable(UrlBitmapDrawable.this); | |
} | |
} | |
} | |
else { | |
mFailed = true; | |
} | |
mRetrieving = false; | |
} | |
}; | |
////////////////////////////////////////////////////////////////////////// | |
// These are stand-ins for an actual image loading library | |
public static interface MyImageCallbacks { | |
public void onLoad(Bitmap bitmap); | |
} | |
private static class MyImageLib { | |
private static void loadImage(String url, MyImageCallbacks callbacks) { | |
// Implement an image loading library here | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Just a heads up, it looks like
setBitmap
is now private inBitmapDrawable
. Any idea how to get around that?