Reputation: 3970
What is the best approach to using SkiaSharp in a native Xamarin project? The goal being to write the canvasView's once and share them between iOS and Android.
My first attempt at doing this was to create a shared project that the iOS and Android project references. Using this approach I am able to do something like this.
using System;
using SkiaSharp;
#if __IOS__
using SkiaSharp.Views.iOS;
using Foundation;
#elif __ANDROID__
using SkiaSharp.Views.Android;
using Android.Content;
using Android.Runtime;
using Android.Util;
#endif
namespace SkiaComponents
{
[Register("TestView")]
public class TestView : SKCanvasView
{
#if __ANDROID__
public TestView(Context context) : base(context)
{
}
public TestView(Context context, IAttributeSet attrs) : base(context, attrs)
{
}
public TestView(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
{
}
protected TestView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
#endif
protected override void OnPaintSurface(SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
var paint = new SKPaint {Style = SKPaintStyle.Stroke, Color = SKColors.Blue, StrokeWidth = 25};
canvas.DrawCircle(info.Width / 2, info.Height / 2, 100, paint);
}
}
}
However this feels kind of clunky to me. Is there a better approach?
Upvotes: 1
Views: 733
Reputation: 1144
I don't think using #ifdefs is the best approach. Use SKCanvasView on every platform project natively without #ifdef and call common code to draw to Canvas. Create class library with common drawing code - shared with every platform (it can be even web). Use advantage of netstandard - it still can reference SkiaSharp NuGet - native for every platform will be used when app is compiled.
Android/iOS code:
protected override void OnPaintSurface(SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
CommonCode.DrawCanvas1(canvas, info);
}
Common code (netstandard20 library)
private void DrawCanvas1(SKSurface surface, SKImageInfo info)
{
using var paint = new SKPaint {Style = SKPaintStyle.Stroke, Color = SKColors.Blue, StrokeWidth = 25};
canvas.DrawCircle(info.Width / 2, info.Height / 2, 100, paint);
}
I use SkiaSharp on 3 different platforms (iOS, Android, WPF) using this approach. I think Xamarin Native has nice benefits - compared to Xamarin Forms you are closer to hardware, app are usually smaller, start faster and still can reuse a lot of code.
Upvotes: 1