GradientProgressBar: Accepting touch input Skiasharp

  • 3 min read

Hi techies, this is another quick post about SkiaSharp and this little control made with it.

When I published a post about SkiaSharp (you can check it out here) some people told me whether or not I could make this progress bar editable, so a user can click and update the progress. So let’s do it and reviewing how SkiaSharp handles touch events.


If you prefer to check the code directly you could go directly to the repository on Github

Let’s do it

Ok, to begin with, we must provide a constructor to our control and enable touch events in SkiaSharp, easy.

public class GradientProgressBar: SKCanvasView { public GradientProgressBar() { EnableTouchEvents = true; } …

In order to calculate the percentage based on touch position, I need a scale factor to convert between Xamarin.Forms units and SkiaSharp units (kind of pixel unit) so I defined a protected float field called ScaleFactor;

protected float ScaleFactor;

I’ve been calculating this factor in OnPaintSurface so I just need to set this value to our ScaleFactor field.

protected override void OnPaintSurface(SKPaintSurfaceEventArgs e) { var info = e.Info; var canvas = e.Surface.Canvas;

    float width = (float)Width;
    var scale = CanvasSize.Width / width;
    ScaleFactor = scale;

With all this plumbing in place (not much to be honest), I can show you the magic. I should override the OnTouch method in order to process touch events. This method receives an instance of SKTouchEventArgs that give us all information available about this interaction.

I interested in handling changes while users are still touching the progress bar, not only at the start of interaction or the end, so I handled SKTouchAction.Pressed, SKTouchAction.Released and SKTouchAction.Moved. You can check more detail about this enum here.

Then, I must calculate the new percentage in our progress bar considering touch position, for this our SKTouchEventArgs instance (e) provides me with Location property and X value.

Thinking about math here, if I know 100% width and current x value, based on the rule of 3, the percentage would be equal to current x value divided by 100% width value.

I like to add this Math.Max for the percentage to avoid values falling behind zero and this Math.Min for Location.X to avoid values going further than 100%.

And the final touch (=D funny if you caught it), is the e.Handled = true, to avoid event bubbling.

And that’s it, our control receives touch input to set percentage if you required.

PD: You can turn off this behaviour just setting this control to disabled (Enabled=false on XAML or code).


Disqus comment here

Recommended for You

Animating our Gradient Progress Bar Control in Xamarin.Forms

Animating our Gradient Progress Bar Control in Xamarin.Forms

Xamarin.Forms: Customizing our Entry control (Custom renderer)

Xamarin.Forms: Customizing our Entry control (Custom renderer)