diff options
Diffstat (limited to 'Xamarin.Forms.Platform.Android/FastRenderers/ImageRenderer.cs')
-rw-r--r-- | Xamarin.Forms.Platform.Android/FastRenderers/ImageRenderer.cs | 86 |
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); } |