问询Xamarin中基于SkiaSharp的跨平台触摸绘图解决方案
Cross-Platform Touch Drawing with SkiaSharp & TouchTracking in Xamarin.Forms
Great question! I’ve tackled this exact scenario before, and there’s a solid cross-platform solution using SkiaSharp and the official TouchTracking libraries that avoids the beta version headaches you mentioned. Here’s how to implement it properly:
Step 1: Install Stable NuGet Packages
Skip the outdated 0.1.0 beta versions—use these maintained, cross-platform packages:
SkiaSharp.Views.Forms: SkiaSharp’s official Xamarin.Forms integration for canvas renderingTouchTracking.Forms: The stable, cross-platform touch event library (matches the coreTouchTrackingnamespace)
Step 2: Replace BoxView with SKCanvasView
Instead of using a BoxView, use SKCanvasView directly—it’s optimized for SkiaSharp drawing and works seamlessly with touch tracking.
Step 3: Implement Touch Handling & Drawing
Here’s a complete working example:
XAML Layout
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms" xmlns:tt="clr-namespace:TouchTracking.Forms;assembly=TouchTracking.Forms" x:Class="DrawApp.MainPage"> <skia:SKCanvasView x:Name="canvasView" BackgroundColor="White"> <tt:TouchEffect.TouchActions> <tt:TouchActionEventHandler> <x:Arguments> <x:String>OnCanvasTouch</x:String> </x:Arguments> </tt:TouchActionEventHandler> </tt:TouchEffect.TouchActions> </skia:SKCanvasView> </ContentPage>
Code-Behind Logic
using SkiaSharp; using SkiaSharp.Views.Forms; using TouchTracking; using Xamarin.Forms; namespace DrawApp { public partial class MainPage : ContentPage { private SKPath _currentDrawPath; private readonly List<SKPath> _savedPaths = new List<SKPath>(); private readonly SKPaint _drawPaint = new SKPaint { Style = SKPaintStyle.Stroke, Color = SKColors.DarkBlue, StrokeWidth = 6, StrokeCap = SKStrokeCap.Round, // Smooths line ends StrokeJoin = SKStrokeJoin.Round // Smooths line corners }; public MainPage() { InitializeComponent(); canvasView.PaintSurface += RenderCanvas; } private void OnCanvasTouch(object sender, TouchActionEventArgs args) { switch (args.Type) { case TouchActionType.Pressed: // Start a new path when the user touches the screen _currentDrawPath = new SKPath(); _currentDrawPath.MoveTo(args.Location); break; case TouchActionType.Moved: // Add to the path as the user drags their finger _currentDrawPath?.LineTo(args.Location); canvasView.InvalidateSurface(); // Trigger redraw break; case TouchActionType.Released: // Save the completed path and reset the current path if (_currentDrawPath != null) { _savedPaths.Add(_currentDrawPath); canvasView.InvalidateSurface(); } _currentDrawPath = null; break; case TouchActionType.Cancelled: // Discard the current path if the touch is interrupted _currentDrawPath = null; break; } } private void RenderCanvas(object sender, SKPaintSurfaceEventArgs args) { var canvas = args.Surface.Canvas; canvas.Clear(SKColors.White); // Clear the canvas each frame // Draw all saved paths foreach (var path in _savedPaths) { canvas.DrawPath(path, _drawPaint); } // Draw the current in-progress path if (_currentDrawPath != null) { canvas.DrawPath(_currentDrawPath, _drawPaint); } } } }
Key Advantages of This Approach
- Fully Cross-Platform: Works on iOS, Android, and UWP without platform-specific code
- Stable Libraries: No beta versions—both packages are actively maintained
- Seamless Integration:
TouchTracking.Formsuses the same coreTouchTrackingnamespace and plays nicely with SkiaSharp’s canvas system - Extensible: Add features like color pickers, stroke width adjustment, or save/load functionality by modifying the
SKPaintsettings or_savedPathscollection
内容的提问来源于stack exchange,提问作者Kyoshiro Kokujou Obscuritas
相关产品推荐
相关产品推荐

