Hackmodford
Hackmodford

Reputation: 3970

Using SkiSharp in a Xamarin native project

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.

enter image description here

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

Answers (1)

Michal Dobrodenka
Michal Dobrodenka

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

Related Questions