summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.Android/FastRenderers/ImageRenderer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Xamarin.Forms.Platform.Android/FastRenderers/ImageRenderer.cs')
-rw-r--r--Xamarin.Forms.Platform.Android/FastRenderers/ImageRenderer.cs86
1 files changed, 65 insertions, 21 deletions
diff --git a/Xamarin.Forms.Platform.Android/FastRenderers/ImageRenderer.cs b/Xamarin.Forms.Platform.Android/FastRenderers/ImageRenderer.cs
index 845ec449..5ca1bd20 100644
--- a/Xamarin.Forms.Platform.Android/FastRenderers/ImageRenderer.cs
+++ b/Xamarin.Forms.Platform.Android/FastRenderers/ImageRenderer.cs
@@ -1,8 +1,10 @@
using System;
using System.ComponentModel;
+using System.Threading.Tasks;
using AImageView = Android.Widget.ImageView;
using AView = Android.Views.View;
using Android.Views;
+using Xamarin.Forms.Internals;
namespace Xamarin.Forms.Platform.Android.FastRenderers
{
@@ -17,30 +19,32 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
protected override void Dispose(bool disposing)
{
- base.Dispose(disposing);
-
if (_disposed)
return;
_disposed = true;
- if (!disposing)
- return;
-
- if (_visualElementTracker != null)
+ if (disposing)
{
- _visualElementTracker.Dispose();
- _visualElementTracker = null;
+ if (_visualElementTracker != null)
+ {
+ _visualElementTracker.Dispose();
+ _visualElementTracker = null;
+ }
+
+ if (_visualElementRenderer != null)
+ {
+ _visualElementRenderer.Dispose();
+ _visualElementRenderer = null;
+ }
+
+ if (_element != null)
+ {
+ _element.PropertyChanged -= OnElementPropertyChanged;
+ }
}
- if (_visualElementRenderer != null)
- {
- _visualElementRenderer.Dispose();
- _visualElementRenderer = null;
- }
-
- if (_element != null)
- _element.PropertyChanged -= OnElementPropertyChanged;
+ base.Dispose(disposing);
}
public override void Invalidate()
@@ -54,9 +58,9 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
base.Invalidate();
}
- protected virtual void OnElementChanged(ElementChangedEventArgs<Image> e)
+ protected virtual async void OnElementChanged(ElementChangedEventArgs<Image> e)
{
- this.UpdateBitmap(e.NewElement, e.OldElement);
+ await TryUpdateBitmap(e.OldElement);
UpdateAspect();
ElementChanged?.Invoke(this, new VisualElementChangedEventArgs(e.OldElement, e.NewElement));
@@ -77,6 +81,11 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
SizeRequest IVisualElementRenderer.GetDesiredSize(int widthConstraint, int heightConstraint)
{
+ if (_disposed)
+ {
+ return new SizeRequest();
+ }
+
Measure(widthConstraint, heightConstraint);
return new SizeRequest(new Size(MeasuredWidth, MeasuredHeight), MinimumSize());
}
@@ -114,7 +123,7 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
_element?.SendViewInitialized(Control);
}
-
+
void IVisualElementRenderer.SetLabelFor(int? id)
{
if (_defaultLabelFor == null)
@@ -144,18 +153,53 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
{
}
- protected virtual void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
+ protected virtual async void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == Image.SourceProperty.PropertyName)
- this.UpdateBitmap(_element);
+ await TryUpdateBitmap();
else if (e.PropertyName == Image.AspectProperty.PropertyName)
UpdateAspect();
ElementPropertyChanged?.Invoke(this, e);
}
+ protected virtual async Task TryUpdateBitmap(Image previous = null)
+ {
+ // By default we'll just catch and log any exceptions thrown by UpdateBitmap so they don't bring down
+ // the application; a custom renderer can override this method and handle exceptions from
+ // UpdateBitmap differently if it wants to
+
+ try
+ {
+ await UpdateBitmap(previous);
+ }
+ catch (Exception ex)
+ {
+ Log.Warning(nameof(ImageRenderer), "Error loading image: {0}", ex);
+ }
+ finally
+ {
+ ((IImageController)_element)?.SetIsLoading(false);
+ }
+ }
+
+ protected async Task UpdateBitmap(Image previous = null)
+ {
+ if (_element == null || _disposed)
+ {
+ return;
+ }
+
+ await Control.UpdateBitmap(_element, previous);
+ }
+
void UpdateAspect()
{
+ if (_element == null || _disposed)
+ {
+ return;
+ }
+
ScaleType type = _element.Aspect.ToScaleType();
SetScaleType(type);
}