Last active
August 29, 2015 14:08
-
-
Save tombowers/085afd46bbd55fd67758 to your computer and use it in GitHub Desktop.
Xamarin Android – Using Remote Images in Lists
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
/// <summary> | |
/// An AsyncTask that will asynchronously download an image and assign it to an ImageView. | |
/// </summary> | |
public class BitmapDownloaderTask : AsyncTask<String, Java.Lang.Void, Bitmap> | |
{ | |
private readonly ImageView _imageView; | |
public BitmapDownloaderTask(ImageView imageView) | |
{ | |
if (imageView == null) | |
throw new ArgumentNullException("imageView"); | |
_imageView = imageView; | |
} | |
public string Url { get; private set; } | |
/// <summary> | |
/// Called on a background thread when the task is executed. | |
/// </summary> | |
protected override Bitmap RunInBackground(params string[] @params) | |
{ | |
Url = @params[0]; | |
return DownloadRemoteImage(Url); | |
} | |
/// <summary> | |
/// Once the image is downloaded, associates it to the imageView | |
/// </summary> | |
protected override void OnPostExecute(Bitmap bitmap) | |
{ | |
if (IsCancelled) | |
bitmap = null; | |
imageView.SetImageBitmap(bitmap); | |
} | |
private Bitmap DownloadRemoteImage(string url) | |
{ | |
if (string.IsNullOrWhiteSpace(url)) | |
throw new ArgumentException("url must not be null, empty, or whitespace"); | |
Uri imageUri; | |
if (!Uri.TryCreate(url, UriKind.Absolute, out imageUri)) | |
throw new ArgumentException("Invalid url"); | |
try | |
{ | |
WebRequest request = HttpWebRequest.Create(imageUri); | |
request.Timeout = 10000; | |
WebResponse response = request.GetResponse(); | |
Stream inputStream = response.GetResponseStream(); | |
return BitmapFactory.DecodeStream(inputStream); | |
} | |
catch (Exception) | |
{ | |
return null; | |
} | |
} | |
} |
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
/// <summary> | |
/// An AsyncTask that will asynchronously download an image and assign it to an ImageView. | |
/// </summary> | |
public class BitmapDownloaderTask : AsyncTask<String, Java.Lang.Void, Bitmap> | |
{ | |
private readonly WeakReference<ImageView> _imageViewReference; | |
public BitmapDownloaderTask(ImageView imageView) | |
{ | |
if (imageView == null) | |
throw new ArgumentNullException("imageView"); | |
_imageViewReference = new WeakReference<ImageView>(imageView); | |
} | |
... | |
/// <summary> | |
/// Once the image is downloaded, associates it to the imageView | |
/// </summary> | |
protected override void OnPostExecute(Bitmap bitmap) | |
{ | |
if (IsCancelled) | |
bitmap = null; | |
if (_imageViewReference != null && bitmap != null) | |
{ | |
ImageView imageView; | |
if (!_imageViewReference.TryGetTarget(out imageView)) | |
return; | |
var bitmapDownloaderTask = imageView.GetBitmapDownloaderTask(); | |
// Change bitmap only if this process is still associated with it. | |
// This is necessary as views can be reused by Android, and a newer BitmapDownloader instance may have been attached to it. | |
if (this == bitmapDownloaderTask) | |
imageView.SetImageBitmap(bitmap); | |
} | |
} | |
... | |
} |
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
var task = new BitmapDownloaderTask(imageView); | |
imageView.SetImageDrawable(new DownloadedDrawable(task, Color.Gray)); | |
imageView.SetMinimumHeight(300); | |
task.Execute("http://placehold.it/300x300"); |
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
var task = new BitmapDownloaderTask(imageView); | |
imageView.SetImageDrawable(new ColorDrawable(Color.Gray)); | |
imageView.SetMinimumHeight(300); | |
task.Execute("http://placehold.it/300x300"); |
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
/// <summary> | |
/// Retrieve the BitmapDownloaderTask from the ImageView's drawable. | |
/// This will return null if the drawable is not a DownloadedDrawable, or there is no BitmapDownloaderTask attached to it. | |
/// </summary> | |
public static BitmapDownloaderTask GetBitmapDownloaderTask(this ImageView imageView) | |
{ | |
if (imageView != null) | |
{ | |
var drawable = imageView.Drawable as DownloadedDrawable; | |
if (drawable != null) | |
return drawable.GetBitmapDownloaderTask(); | |
} | |
return null; | |
} |
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
/// <summary> | |
/// A fake Drawable that will be attached to the ImageView while the download is in progress. | |
/// Contains a reference to the actual download task, so that a download task can be stopped | |
/// if a new binding is required, and makes sure that only the last started download process can | |
/// bind its result, independently of the download finish order. | |
/// </summary> | |
public class DownloadedDrawable : ColorDrawable | |
{ | |
private readonly WeakReference<BitmapDownloaderTask> _bitmapDownloaderTaskReference; | |
public DownloadedDrawable(BitmapDownloaderTask bitmapDownloaderTask, Color loadingBackgroundColor) | |
: base(loadingBackgroundColor) | |
{ | |
_bitmapDownloaderTaskReference = new WeakReference<BitmapDownloaderTask>(bitmapDownloaderTask); | |
} | |
public BitmapDownloaderTask GetBitmapDownloaderTask() | |
{ | |
BitmapDownloaderTask task; | |
_bitmapDownloaderTaskReference.TryGetTarget(out task); | |
return task; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment