Skip to content

Commit

Permalink
Added IImageSourceHandler for iOS / Mac / Android
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-luberda committed May 6, 2019
1 parent ddf2ad5 commit 6566737
Show file tree
Hide file tree
Showing 19 changed files with 282 additions and 89 deletions.
2 changes: 1 addition & 1 deletion nuget/Xamarin.FFImageLoading.Forms.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Features:

<group>
<dependency id="Xamarin.FFImageLoading" version="@version" />
<dependency id="Xamarin.Forms" version="2.4" />
<dependency id="Xamarin.Forms" version="3.3.0.912540" />
</group>

</dependencies>
Expand Down
1 change: 1 addition & 0 deletions samples/ImageLoading.Forms.Sample/Mac/AppDelegate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public override void DidFinishLaunching(NSNotification notification)
{
Xamarin.Forms.Forms.Init();
CachedImageRenderer.Init();
CachedImageRenderer.InitImageSourceHandler();
LoadApplication(new App());
base.DidFinishLaunching(notification);
}
Expand Down
1 change: 1 addition & 0 deletions samples/ImageLoading.Forms.Sample/iOS/AppDelegate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
CachedImageRenderer.Init();
CachedImageRenderer.InitImageSourceHandler();

var config = new FFImageLoading.Config.Configuration()
{
Expand Down
5 changes: 5 additions & 0 deletions source/FFImageLoading.Droid/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,8 @@
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]

[assembly: InternalsVisibleTo("FFImageLoading.Tests")]
[assembly: InternalsVisibleTo("FFImageLoading.Platform")]
[assembly: InternalsVisibleTo("FFImageLoading.Svg.Platform")]
[assembly: InternalsVisibleTo("FFImageLoading.Forms")]
[assembly: InternalsVisibleTo("FFImageLoading.Forms.Platform")]
8 changes: 4 additions & 4 deletions source/FFImageLoading.Forms.Droid/CachedImageRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ public static void Init(bool? enableFastRenderer)
}

/// <summary>
/// Call this after Xamarin.Forms.Init to use FFImageLoading in all Xamarin.Forms views
/// Including Xamarin.Forms.Image
/// Call this after Xamarin.Forms.Init to use FFImageLoading in all Xamarin.Forms views,
/// including Xamarin.Forms.Image
/// </summary>
public static void InitImageViewHandler()
{
Expand All @@ -68,8 +68,8 @@ public static void InitImageViewHandler()
Helpers.Dependency.Register(typeof(EmbeddedResourceImageSource), typeof(FFImageLoadingImageViewHandler));
Helpers.Dependency.Register(typeof(DataUrlImageSource), typeof(FFImageLoadingImageViewHandler));
}
private bool _isDisposed;

private bool _isDisposed;
private IScheduledWork _currentTask;
private ImageSourceBinding _lastImageSource;
private readonly MotionEventHelper _motionEventHelper = CachedImage.FixedAndroidMotionEventHandler ? new MotionEventHelper() : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="CachedImageFastRenderer.cs" />
<Compile Include="FFImageLoadingImageViewHandler.cs" />
<Compile Include="FFImageLoadingImageSourceHandler.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Android.Content;
using Android.Graphics;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using FFImageLoading.Forms.Handlers;
using FFImageLoading.Work;
using FFImageLoading.Targets;

namespace FFImageLoading.Forms.Platform
{
public class FFImageLoadingImageSourceHandler : HandlerBase<Context>, IImageSourceHandler
{
public async Task<Bitmap> LoadImageAsync(Xamarin.Forms.ImageSource imageSource, Context context, CancellationToken cancellationToken = default)
{
try
{
if (!IsValid(context))
return null;

var source = ImageSourceBinding.GetImageSourceBinding(imageSource, null);
if (source == null)
{
return null;
}

var result = await LoadImageAsync(source, imageSource, context, cancellationToken);
var target = result.Target as BitmapTarget;
return target?.BitmapDrawable?.Bitmap;
}
catch (Exception)
{
return null;
}
}

private static bool IsValid(Context context)
{
if (context == null || context.Handle == IntPtr.Zero)
return false;

#pragma warning disable CS0618 // Type or member is obsolete
var activity = context as Android.App.Activity ?? (Android.App.Activity)Xamarin.Forms.Forms.Context;
#pragma warning restore CS0618 // Type or member is obsolete
if (activity != null)
{
if (activity.IsFinishing)
return false;
if (activity.IsDestroyed)
return false;
}
else
{
return false;
}

return true;
}

protected override IImageLoaderTask GetImageLoaderTask(TaskParameter parameters, Context imageView)
{
var target = new BitmapTarget();
var task = ImageService.CreateTask(parameters, target);
ImageService.Instance.LoadImage(task);
return task;
}
}
}
107 changes: 24 additions & 83 deletions source/FFImageLoading.Forms.Droid/FFImageLoadingImageViewHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
using System.Threading;
using System.Threading.Tasks;
using FFImageLoading.Work;

#if __ANDROID__
using Android.Widget;
using FFImageLoading.Forms.Handlers;
using Xamarin.Forms.Platform.Android;
using TNativeImageView = Android.Widget.ImageView;
#endif

//[assembly: Xamarin.Forms.ExportImageSourceHandler(typeof(Xamarin.Forms.FileImageSource), typeof(FFImageLoading.Forms.Platform.FFImageLoadingImageViewHandler))]
//[assembly: Xamarin.Forms.ExportImageSourceHandler(typeof(Xamarin.Forms.StreamImageSource), typeof(FFImageLoading.Forms.Platform.FFImageLoadingImageViewHandler))]
Expand All @@ -17,99 +15,38 @@
namespace FFImageLoading.Forms.Platform
{
[Preserve(AllMembers = true)]
public class FFImageLoadingImageViewHandler : IImageViewHandler
public class FFImageLoadingImageViewHandler : HandlerBase<ImageView>, IImageViewHandler
{
public Task LoadImageAsync(Xamarin.Forms.ImageSource imagesource, TNativeImageView imageView, CancellationToken cancellationToken = default)
public Task LoadImageAsync(Xamarin.Forms.ImageSource imageSource, ImageView imageView, CancellationToken cancellationToken = default)
{
#if __ANDROID__
if (!IsValid(imageView))
return Task.CompletedTask;
#endif

var source = ImageSourceBinding.GetImageSourceBinding(imagesource, null);
if (source == null)
try
{
#if __ANDROID__
imageView.SetImageResource(Android.Resource.Color.Transparent);
#endif
return Task.CompletedTask;
}
if (!IsValid(imageView))
return Task.CompletedTask;

TaskParameter imageLoader;

if (source.ImageSource == ImageSource.Url)
{
var urlSource = (Xamarin.Forms.UriImageSource)imagesource;
imageLoader = ImageService.Instance.LoadUrl(source.Path, urlSource.CacheValidity);

if (!urlSource.CachingEnabled)
var source = ImageSourceBinding.GetImageSourceBinding(imageSource, null);
if (source == null)
{
imageLoader.WithCache(Cache.CacheType.None);
imageView.SetImageResource(Android.Resource.Color.Transparent);
return Task.CompletedTask;
}

return LoadImageAsync(source, imageSource, imageView, cancellationToken);
}
else if (source.ImageSource == ImageSource.CompiledResource)
{
imageLoader = ImageService.Instance.LoadCompiledResource(source.Path);
}
else if (source.ImageSource == ImageSource.ApplicationBundle)
{
imageLoader = ImageService.Instance.LoadFileFromApplicationBundle(source.Path);
}
else if (source.ImageSource == ImageSource.Filepath)
{
imageLoader = ImageService.Instance.LoadFile(source.Path);
}
else if (source.ImageSource == ImageSource.Stream)
{
imageLoader = ImageService.Instance.LoadStream(source.Stream);
}
else if (source.ImageSource == ImageSource.EmbeddedResource)
{
imageLoader = ImageService.Instance.LoadEmbeddedResource(source.Path);
}
else
catch (Exception)
{
return Task.CompletedTask;
}

if (imageLoader != null)
{
var tcs = new TaskCompletionSource<IScheduledWork>();

imageLoader
.FadeAnimation(false, false)
.Error(ex => {
tcs.TrySetException(ex);
})
.Finish(scheduledWork => {
tcs.TrySetResult(scheduledWork);
});

var task = imageLoader.Into(imageView);

if (cancellationToken != default)
cancellationToken.Register(() =>
{
try
{
task?.Cancel();
}
catch { }
});

return tcs.Task;
}

return Task.CompletedTask;
}
#if __ANDROID__
private static bool IsValid(TNativeImageView imageView)

private static bool IsValid(ImageView imageView)
{
if (imageView == null || imageView.Handle == IntPtr.Zero)
return false;

//NOTE: in some cases ContextThemeWrapper is Context
#pragma warning disable CS0618 // Type or member is obsolete
var activity = imageView.Context as Android.App.Activity ?? (Android.App.Activity)Xamarin.Forms.Forms.Context;
#pragma warning restore CS0618 // Type or member is obsolete
if (activity != null)
{
if (activity.IsFinishing)
Expand All @@ -124,6 +61,10 @@ private static bool IsValid(TNativeImageView imageView)

return true;
}
#endif

protected override IImageLoaderTask GetImageLoaderTask(TaskParameter parameters, ImageView imageView)
{
return parameters.Into(imageView) as IImageLoaderTask;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@
<Compile Include="..\FFImageLoading.Forms.Touch\ImageSourceBinding.cs">
<Link>ImageSourceBinding.cs</Link>
</Compile>
<Compile Include="..\FFImageLoading.Forms.Touch\FFImageLoadingImageSourceHandler.cs">
<Link>FFImageLoadingImageSourceHandler.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FFImageLoading.Common\FFImageLoading.csproj">
Expand Down
15 changes: 14 additions & 1 deletion source/FFImageLoading.Forms.Touch/CachedImageRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,20 @@ internal class _CachedImageRenderer
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}

protected override void Dispose(bool disposing)
/// <summary>
/// Call this after Xamarin.Forms.Init to use FFImageLoading in all Xamarin.Forms views,
/// including Xamarin.Forms.Image
/// </summary>
public static void InitImageSourceHandler()
{
Helpers.Dependency.Register(typeof(FileImageSource), typeof(FFImageLoadingImageSourceHandler));
Helpers.Dependency.Register(typeof(StreamImageSource), typeof(FFImageLoadingImageSourceHandler));
Helpers.Dependency.Register(typeof(UriImageSource), typeof(FFImageLoadingImageSourceHandler));
Helpers.Dependency.Register(typeof(EmbeddedResourceImageSource), typeof(FFImageLoadingImageSourceHandler));
Helpers.Dependency.Register(typeof(DataUrlImageSource), typeof(FFImageLoadingImageSourceHandler));
}

protected override void Dispose(bool disposing)
{
if (!_isDisposed)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="CachedImageRenderer.cs" />
<Compile Include="ImageSourceBinding.cs" />
<Compile Include="FFImageLoadingImageSourceHandler.cs" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using FFImageLoading.Forms.Handlers;
using FFImageLoading.Work;

#if __IOS__
using PImage = UIKit.UIImage;
using PImageTarget = FFImageLoading.Targets.UIImageTarget;
using Xamarin.Forms.Platform.iOS;
#elif __MACOS__
using PImage = AppKit.NSImage;
using PImageTarget = FFImageLoading.Targets.NSImageTarget;
using Xamarin.Forms.Platform.MacOS;
#endif

namespace FFImageLoading.Forms.Platform
{
public class FFImageLoadingImageSourceHandler : HandlerBase<object>, IImageSourceHandler
{
public async Task<PImage> LoadImageAsync(Xamarin.Forms.ImageSource imageSource, CancellationToken cancellationToken = default, float scale = 1)
{
try
{
var source = ImageSourceBinding.GetImageSourceBinding(imageSource, null);
if (source == null)
{
return null;
}

var result = await LoadImageAsync(source, imageSource, null, cancellationToken);
var target = result?.Target as PImageTarget;
return target?.PImage;
}
catch (Exception)
{
return null;
}
}

protected override IImageLoaderTask GetImageLoaderTask(TaskParameter parameters, object imageView)
{
var target = new PImageTarget();
var task = ImageService.CreateTask(parameters, target);
ImageService.Instance.LoadImage(task);
return task;
}
}
}
1 change: 1 addition & 0 deletions source/FFImageLoading.Forms/FFImageLoading.Forms.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,6 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Helpers\" />
<Folder Include="Handlers\" />
</ItemGroup>
</Project>
Loading

0 comments on commit 6566737

Please sign in to comment.