protected async override Task SetTargetAsync(SelfDisposingBitmapDrawable image, bool animated) { if (Target == null) { return; } ThrowIfCancellationRequested(); var ffDrawable = image as FFBitmapDrawable; if (ffDrawable != null) { if (ffDrawable.IsAnimationRunning) { var mut = new FFBitmapDrawable(Context.Resources, ffDrawable.Bitmap, ffDrawable); ffDrawable = mut as FFBitmapDrawable; image = ffDrawable; // old hacky workaround //await Task.Delay(ffDrawable.FadeDuration + 50).ConfigureAwait(false); } if (animated) { SelfDisposingBitmapDrawable placeholderDrawable = null; PlaceholderWeakReference?.TryGetTarget(out placeholderDrawable); if (placeholderDrawable == null) { // Enable fade animation when no placeholder is set and the previous image is not null var imageView = PlatformTarget.Control as ImageViewAsync; placeholderDrawable = imageView?.Drawable as SelfDisposingBitmapDrawable; } if (placeholderDrawable.IsValidAndHasValidBitmap()) { int fadeDuration = Parameters.FadeAnimationDuration.HasValue ? Parameters.FadeAnimationDuration.Value : Configuration.FadeAnimationDuration; placeholderDrawable?.SetIsRetained(true); ffDrawable?.SetPlaceholder(placeholderDrawable, fadeDuration); placeholderDrawable?.SetIsRetained(false); } } else { ffDrawable?.SetPlaceholder(null, 0); } } await MainThreadDispatcher.PostAsync(() => { ThrowIfCancellationRequested(); PlatformTarget.Set(this, image, animated); }).ConfigureAwait(false); }
protected async override Task SetTargetAsync(SelfDisposingBitmapDrawable image, bool animated) { ThrowIfCancellationRequested(); var ffDrawable = image as FFBitmapDrawable; if (ffDrawable != null) { if (ffDrawable.IsAnimationRunning) { var mut = new FFBitmapDrawable(Context.Resources, ffDrawable.Bitmap, ffDrawable); ffDrawable = mut as FFBitmapDrawable; image = ffDrawable; // old hacky workaround //await Task.Delay(ffDrawable.FadeDuration + 50).ConfigureAwait(false); } if (animated) { SelfDisposingBitmapDrawable placeholderDrawable = null; if (PlaceholderWeakReference != null && PlaceholderWeakReference.TryGetTarget(out placeholderDrawable) && placeholderDrawable != null) { int fadeDuration = Parameters.FadeAnimationDuration.HasValue ? Parameters.FadeAnimationDuration.Value : Configuration.FadeAnimationDuration; placeholderDrawable?.SetIsRetained(true); ffDrawable?.SetPlaceholder(placeholderDrawable, fadeDuration); placeholderDrawable?.SetIsRetained(false); } } else { ffDrawable?.SetPlaceholder(null, 0); } } await MainThreadDispatcher.PostAsync(() => { ThrowIfCancellationRequested(); PlatformTarget.Set(this, image, animated); }).ConfigureAwait(false); }
protected override Task <SelfDisposingBitmapDrawable> GenerateImageFromDecoderContainerAsync(IDecodedImage <Bitmap> decoded, ImageInformation imageInformation, bool isPlaceholder) { try { SelfDisposingBitmapDrawable result; if (decoded.IsAnimated) { result = new FFAnimatedDrawable(Context.Resources, decoded.AnimatedImages[0].Image, decoded.AnimatedImages); } else { if (isPlaceholder) { result = new SelfDisposingBitmapDrawable(Context.Resources, decoded.Image); } else { result = new FFBitmapDrawable(Context.Resources, decoded.Image); } } if (result == null || !result.HasValidBitmap) { throw new BadImageFormatException("Not a valid bitmap"); } return(Task.FromResult(result)); } catch (Exception ex) { if (ex is Java.Lang.Throwable javaException && javaException.Class == Java.Lang.Class.FromType(typeof(Java.Lang.OutOfMemoryError))) { if (Configuration.ClearMemoryCacheOnOutOfMemory) { Java.Lang.JavaSystem.Gc(); } throw new OutOfMemoryException(); } throw; } }
protected async override Task SetTargetAsync(SelfDisposingBitmapDrawable image, bool animated) { if (Target == null) { return; } ThrowIfCancellationRequested(); if (image is FFBitmapDrawable ffDrawable) { if (ffDrawable.IsAnimationRunning) { var mut = new FFBitmapDrawable(Context.Resources, ffDrawable.Bitmap, ffDrawable); ffDrawable = mut as FFBitmapDrawable; image = ffDrawable; // old hacky workaround //await Task.Delay(ffDrawable.FadeDuration + 50).ConfigureAwait(false); } if (animated) { SelfDisposingBitmapDrawable placeholderDrawable = null; PlaceholderWeakReference?.TryGetTarget(out placeholderDrawable); if (placeholderDrawable == null) { // Enable fade animation when no placeholder is set and the previous image is not null var imageView = PlatformTarget.Control as ImageViewAsync; placeholderDrawable = imageView?.Drawable as SelfDisposingBitmapDrawable; } var fadeDuration = Parameters.FadeAnimationDuration ?? Configuration.FadeAnimationDuration; if (placeholderDrawable.IsValidAndHasValidBitmap()) { placeholderDrawable?.SetIsRetained(true); ffDrawable?.SetPlaceholder(placeholderDrawable, fadeDuration); placeholderDrawable?.SetIsRetained(false); } else if (ffDrawable.IsValidAndHasValidBitmap()) { var width = ffDrawable.Bitmap.Width; var height = ffDrawable.Bitmap.Height; var bitmap = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888); using (var canvas = new Canvas(bitmap)) using (var paint = new Paint() { Color = _placeholderHelperColor }) { canvas.DrawRect(0, 0, width, height, paint); } ffDrawable?.SetPlaceholder(new SelfDisposingBitmapDrawable(Context.Resources, bitmap), fadeDuration); } } else { ffDrawable?.SetPlaceholder(null, 0); } } await MainThreadDispatcher.PostAsync(() => { ThrowIfCancellationRequested(); PlatformTarget.Set(this, image, animated); }).ConfigureAwait(false); }