Skip to content

Commit 6566737

Browse files
Added IImageSourceHandler for iOS / Mac / Android
1 parent ddf2ad5 commit 6566737

File tree

19 files changed

+282
-89
lines changed

19 files changed

+282
-89
lines changed

nuget/Xamarin.FFImageLoading.Forms.nuspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Features:
4545

4646
<group>
4747
<dependency id="Xamarin.FFImageLoading" version="@version" />
48-
<dependency id="Xamarin.Forms" version="2.4" />
48+
<dependency id="Xamarin.Forms" version="3.3.0.912540" />
4949
</group>
5050

5151
</dependencies>

samples/ImageLoading.Forms.Sample/Mac/AppDelegate.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public override void DidFinishLaunching(NSNotification notification)
2929
{
3030
Xamarin.Forms.Forms.Init();
3131
CachedImageRenderer.Init();
32+
CachedImageRenderer.InitImageSourceHandler();
3233
LoadApplication(new App());
3334
base.DidFinishLaunching(notification);
3435
}

samples/ImageLoading.Forms.Sample/iOS/AppDelegate.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public override bool FinishedLaunching(UIApplication app, NSDictionary options)
1414
{
1515
global::Xamarin.Forms.Forms.Init();
1616
CachedImageRenderer.Init();
17+
CachedImageRenderer.InitImageSourceHandler();
1718

1819
var config = new FFImageLoading.Config.Configuration()
1920
{

source/FFImageLoading.Droid/Properties/AssemblyInfo.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,8 @@
2525
//[assembly: AssemblyDelaySign(false)]
2626
//[assembly: AssemblyKeyFile("")]
2727

28+
[assembly: InternalsVisibleTo("FFImageLoading.Tests")]
29+
[assembly: InternalsVisibleTo("FFImageLoading.Platform")]
30+
[assembly: InternalsVisibleTo("FFImageLoading.Svg.Platform")]
31+
[assembly: InternalsVisibleTo("FFImageLoading.Forms")]
32+
[assembly: InternalsVisibleTo("FFImageLoading.Forms.Platform")]

source/FFImageLoading.Forms.Droid/CachedImageRenderer.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ public static void Init(bool? enableFastRenderer)
5757
}
5858

5959
/// <summary>
60-
/// Call this after Xamarin.Forms.Init to use FFImageLoading in all Xamarin.Forms views
61-
/// Including Xamarin.Forms.Image
60+
/// Call this after Xamarin.Forms.Init to use FFImageLoading in all Xamarin.Forms views,
61+
/// including Xamarin.Forms.Image
6262
/// </summary>
6363
public static void InitImageViewHandler()
6464
{
@@ -68,8 +68,8 @@ public static void InitImageViewHandler()
6868
Helpers.Dependency.Register(typeof(EmbeddedResourceImageSource), typeof(FFImageLoadingImageViewHandler));
6969
Helpers.Dependency.Register(typeof(DataUrlImageSource), typeof(FFImageLoadingImageViewHandler));
7070
}
71-
72-
private bool _isDisposed;
71+
72+
private bool _isDisposed;
7373
private IScheduledWork _currentTask;
7474
private ImageSourceBinding _lastImageSource;
7575
private readonly MotionEventHelper _motionEventHelper = CachedImage.FixedAndroidMotionEventHandler ? new MotionEventHelper() : null;

source/FFImageLoading.Forms.Droid/FFImageLoading.Forms.Droid.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@
135135
<Compile Include="Properties\AssemblyInfo.cs" />
136136
<Compile Include="CachedImageFastRenderer.cs" />
137137
<Compile Include="FFImageLoadingImageViewHandler.cs" />
138+
<Compile Include="FFImageLoadingImageSourceHandler.cs" />
138139
</ItemGroup>
139140
<ItemGroup>
140141
<None Include="app.config" />
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
using System;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
using Android.Content;
5+
using Android.Graphics;
6+
using Xamarin.Forms;
7+
using Xamarin.Forms.Platform.Android;
8+
using FFImageLoading.Forms.Handlers;
9+
using FFImageLoading.Work;
10+
using FFImageLoading.Targets;
11+
12+
namespace FFImageLoading.Forms.Platform
13+
{
14+
public class FFImageLoadingImageSourceHandler : HandlerBase<Context>, IImageSourceHandler
15+
{
16+
public async Task<Bitmap> LoadImageAsync(Xamarin.Forms.ImageSource imageSource, Context context, CancellationToken cancellationToken = default)
17+
{
18+
try
19+
{
20+
if (!IsValid(context))
21+
return null;
22+
23+
var source = ImageSourceBinding.GetImageSourceBinding(imageSource, null);
24+
if (source == null)
25+
{
26+
return null;
27+
}
28+
29+
var result = await LoadImageAsync(source, imageSource, context, cancellationToken);
30+
var target = result.Target as BitmapTarget;
31+
return target?.BitmapDrawable?.Bitmap;
32+
}
33+
catch (Exception)
34+
{
35+
return null;
36+
}
37+
}
38+
39+
private static bool IsValid(Context context)
40+
{
41+
if (context == null || context.Handle == IntPtr.Zero)
42+
return false;
43+
44+
#pragma warning disable CS0618 // Type or member is obsolete
45+
var activity = context as Android.App.Activity ?? (Android.App.Activity)Xamarin.Forms.Forms.Context;
46+
#pragma warning restore CS0618 // Type or member is obsolete
47+
if (activity != null)
48+
{
49+
if (activity.IsFinishing)
50+
return false;
51+
if (activity.IsDestroyed)
52+
return false;
53+
}
54+
else
55+
{
56+
return false;
57+
}
58+
59+
return true;
60+
}
61+
62+
protected override IImageLoaderTask GetImageLoaderTask(TaskParameter parameters, Context imageView)
63+
{
64+
var target = new BitmapTarget();
65+
var task = ImageService.CreateTask(parameters, target);
66+
ImageService.Instance.LoadImage(task);
67+
return task;
68+
}
69+
}
70+
}

source/FFImageLoading.Forms.Droid/FFImageLoadingImageViewHandler.cs

Lines changed: 24 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22
using System.Threading;
33
using System.Threading.Tasks;
44
using FFImageLoading.Work;
5-
6-
#if __ANDROID__
5+
using Android.Widget;
6+
using FFImageLoading.Forms.Handlers;
77
using Xamarin.Forms.Platform.Android;
8-
using TNativeImageView = Android.Widget.ImageView;
9-
#endif
108

119
//[assembly: Xamarin.Forms.ExportImageSourceHandler(typeof(Xamarin.Forms.FileImageSource), typeof(FFImageLoading.Forms.Platform.FFImageLoadingImageViewHandler))]
1210
//[assembly: Xamarin.Forms.ExportImageSourceHandler(typeof(Xamarin.Forms.StreamImageSource), typeof(FFImageLoading.Forms.Platform.FFImageLoadingImageViewHandler))]
@@ -17,99 +15,38 @@
1715
namespace FFImageLoading.Forms.Platform
1816
{
1917
[Preserve(AllMembers = true)]
20-
public class FFImageLoadingImageViewHandler : IImageViewHandler
18+
public class FFImageLoadingImageViewHandler : HandlerBase<ImageView>, IImageViewHandler
2119
{
22-
public Task LoadImageAsync(Xamarin.Forms.ImageSource imagesource, TNativeImageView imageView, CancellationToken cancellationToken = default)
20+
public Task LoadImageAsync(Xamarin.Forms.ImageSource imageSource, ImageView imageView, CancellationToken cancellationToken = default)
2321
{
24-
#if __ANDROID__
25-
if (!IsValid(imageView))
26-
return Task.CompletedTask;
27-
#endif
28-
29-
var source = ImageSourceBinding.GetImageSourceBinding(imagesource, null);
30-
if (source == null)
22+
try
3123
{
32-
#if __ANDROID__
33-
imageView.SetImageResource(Android.Resource.Color.Transparent);
34-
#endif
35-
return Task.CompletedTask;
36-
}
24+
if (!IsValid(imageView))
25+
return Task.CompletedTask;
3726

38-
TaskParameter imageLoader;
39-
40-
if (source.ImageSource == ImageSource.Url)
41-
{
42-
var urlSource = (Xamarin.Forms.UriImageSource)imagesource;
43-
imageLoader = ImageService.Instance.LoadUrl(source.Path, urlSource.CacheValidity);
44-
45-
if (!urlSource.CachingEnabled)
27+
var source = ImageSourceBinding.GetImageSourceBinding(imageSource, null);
28+
if (source == null)
4629
{
47-
imageLoader.WithCache(Cache.CacheType.None);
30+
imageView.SetImageResource(Android.Resource.Color.Transparent);
31+
return Task.CompletedTask;
4832
}
33+
34+
return LoadImageAsync(source, imageSource, imageView, cancellationToken);
4935
}
50-
else if (source.ImageSource == ImageSource.CompiledResource)
51-
{
52-
imageLoader = ImageService.Instance.LoadCompiledResource(source.Path);
53-
}
54-
else if (source.ImageSource == ImageSource.ApplicationBundle)
55-
{
56-
imageLoader = ImageService.Instance.LoadFileFromApplicationBundle(source.Path);
57-
}
58-
else if (source.ImageSource == ImageSource.Filepath)
59-
{
60-
imageLoader = ImageService.Instance.LoadFile(source.Path);
61-
}
62-
else if (source.ImageSource == ImageSource.Stream)
63-
{
64-
imageLoader = ImageService.Instance.LoadStream(source.Stream);
65-
}
66-
else if (source.ImageSource == ImageSource.EmbeddedResource)
67-
{
68-
imageLoader = ImageService.Instance.LoadEmbeddedResource(source.Path);
69-
}
70-
else
36+
catch (Exception)
7137
{
7238
return Task.CompletedTask;
7339
}
74-
75-
if (imageLoader != null)
76-
{
77-
var tcs = new TaskCompletionSource<IScheduledWork>();
78-
79-
imageLoader
80-
.FadeAnimation(false, false)
81-
.Error(ex => {
82-
tcs.TrySetException(ex);
83-
})
84-
.Finish(scheduledWork => {
85-
tcs.TrySetResult(scheduledWork);
86-
});
87-
88-
var task = imageLoader.Into(imageView);
89-
90-
if (cancellationToken != default)
91-
cancellationToken.Register(() =>
92-
{
93-
try
94-
{
95-
task?.Cancel();
96-
}
97-
catch { }
98-
});
99-
100-
return tcs.Task;
101-
}
102-
103-
return Task.CompletedTask;
10440
}
105-
#if __ANDROID__
106-
private static bool IsValid(TNativeImageView imageView)
41+
42+
private static bool IsValid(ImageView imageView)
10743
{
10844
if (imageView == null || imageView.Handle == IntPtr.Zero)
10945
return false;
110-
111-
//NOTE: in some cases ContextThemeWrapper is Context
46+
47+
#pragma warning disable CS0618 // Type or member is obsolete
11248
var activity = imageView.Context as Android.App.Activity ?? (Android.App.Activity)Xamarin.Forms.Forms.Context;
49+
#pragma warning restore CS0618 // Type or member is obsolete
11350
if (activity != null)
11451
{
11552
if (activity.IsFinishing)
@@ -124,6 +61,10 @@ private static bool IsValid(TNativeImageView imageView)
12461

12562
return true;
12663
}
127-
#endif
64+
65+
protected override IImageLoaderTask GetImageLoaderTask(TaskParameter parameters, ImageView imageView)
66+
{
67+
return parameters.Into(imageView) as IImageLoaderTask;
68+
}
12869
}
12970
}

source/FFImageLoading.Forms.Mac/FFImageLoading.Forms.Mac.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@
7878
<Compile Include="..\FFImageLoading.Forms.Touch\ImageSourceBinding.cs">
7979
<Link>ImageSourceBinding.cs</Link>
8080
</Compile>
81+
<Compile Include="..\FFImageLoading.Forms.Touch\FFImageLoadingImageSourceHandler.cs">
82+
<Link>FFImageLoadingImageSourceHandler.cs</Link>
83+
</Compile>
8184
</ItemGroup>
8285
<ItemGroup>
8386
<ProjectReference Include="..\FFImageLoading.Common\FFImageLoading.csproj">

source/FFImageLoading.Forms.Touch/CachedImageRenderer.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,20 @@ internal class _CachedImageRenderer
6161
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
6262
}
6363

64-
protected override void Dispose(bool disposing)
64+
/// <summary>
65+
/// Call this after Xamarin.Forms.Init to use FFImageLoading in all Xamarin.Forms views,
66+
/// including Xamarin.Forms.Image
67+
/// </summary>
68+
public static void InitImageSourceHandler()
69+
{
70+
Helpers.Dependency.Register(typeof(FileImageSource), typeof(FFImageLoadingImageSourceHandler));
71+
Helpers.Dependency.Register(typeof(StreamImageSource), typeof(FFImageLoadingImageSourceHandler));
72+
Helpers.Dependency.Register(typeof(UriImageSource), typeof(FFImageLoadingImageSourceHandler));
73+
Helpers.Dependency.Register(typeof(EmbeddedResourceImageSource), typeof(FFImageLoadingImageSourceHandler));
74+
Helpers.Dependency.Register(typeof(DataUrlImageSource), typeof(FFImageLoadingImageSourceHandler));
75+
}
76+
77+
protected override void Dispose(bool disposing)
6578
{
6679
if (!_isDisposed)
6780
{

source/FFImageLoading.Forms.Touch/FFImageLoading.Forms.Touch.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
<Compile Include="Properties\AssemblyInfo.cs" />
6161
<Compile Include="CachedImageRenderer.cs" />
6262
<Compile Include="ImageSourceBinding.cs" />
63+
<Compile Include="FFImageLoadingImageSourceHandler.cs" />
6364
</ItemGroup>
6465
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
6566
<ItemGroup>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
using FFImageLoading.Forms.Handlers;
5+
using FFImageLoading.Work;
6+
7+
#if __IOS__
8+
using PImage = UIKit.UIImage;
9+
using PImageTarget = FFImageLoading.Targets.UIImageTarget;
10+
using Xamarin.Forms.Platform.iOS;
11+
#elif __MACOS__
12+
using PImage = AppKit.NSImage;
13+
using PImageTarget = FFImageLoading.Targets.NSImageTarget;
14+
using Xamarin.Forms.Platform.MacOS;
15+
#endif
16+
17+
namespace FFImageLoading.Forms.Platform
18+
{
19+
public class FFImageLoadingImageSourceHandler : HandlerBase<object>, IImageSourceHandler
20+
{
21+
public async Task<PImage> LoadImageAsync(Xamarin.Forms.ImageSource imageSource, CancellationToken cancellationToken = default, float scale = 1)
22+
{
23+
try
24+
{
25+
var source = ImageSourceBinding.GetImageSourceBinding(imageSource, null);
26+
if (source == null)
27+
{
28+
return null;
29+
}
30+
31+
var result = await LoadImageAsync(source, imageSource, null, cancellationToken);
32+
var target = result?.Target as PImageTarget;
33+
return target?.PImage;
34+
}
35+
catch (Exception)
36+
{
37+
return null;
38+
}
39+
}
40+
41+
protected override IImageLoaderTask GetImageLoaderTask(TaskParameter parameters, object imageView)
42+
{
43+
var target = new PImageTarget();
44+
var task = ImageService.CreateTask(parameters, target);
45+
ImageService.Instance.LoadImage(task);
46+
return task;
47+
}
48+
}
49+
}

source/FFImageLoading.Forms/FFImageLoading.Forms.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,6 @@
4444
</ItemGroup>
4545
<ItemGroup>
4646
<Folder Include="Helpers\" />
47+
<Folder Include="Handlers\" />
4748
</ItemGroup>
4849
</Project>

0 commit comments

Comments
 (0)