Easily animate Xamarin custom controls built with SkiaSharp

Yuriy Holembyovskyy, Lead Xamarin developer

Tech

04.02.2020.

featured image

In the previous article we saw how we can port ios controls to Xamarin.ios and SkiaSharp and make it cross-platform. As a bonus to this article was animation of ported controls.

async Task AnimateProgress1(float progress)
        {
            if (progress == VGaugeControl.Progress)
            {
                return;
            }
            if (progress <= VGaugeControl.Progress)
            {
                for (int i = VGaugeControl.Progress; i >= progress; i--)
                {
                    VGaugeControl.Progress = i;
                    await Task.Delay(1);
                }
            }
            else
            {
                for (int i = VGaugeControl.Progress; i <= progress; i++)
                {
                    VGaugeControl.Progress = i;
                    await Task.Delay(1);
                }
            }
        }
 

Well, this is actually what is going under the hood. There is a more convenient way to animate any Xamarin.Forms control including ones that are built with SkiaSharp. Xamarin.Forms include its own animation infrastructure that's versatile enough to create complex animations.

Let’s see how we can simplify our gauge animation with Xamarin. Forms built-in infrastructure.

void AnimateProgress1(float progress)
  {
      var animation = new Animation(v => VGaugeControl.Progress = (int)v, startHValue,  
      progress, easing: Easing.SinInOut);
      animation.Commit(VGaugeControl, "Progress", length: 2000, finished: (l, c) =>
      animation = null);           
   }

Animation object receives a callback as a parameter, this callback receives parameters that represent the actual value in the animation progression between the actual (startValue) and desired value (progress).

Easing function

The most interesting parameter for us is the easing function. You can read more here about these functions.

Easing.SinInOut
Easing.SinInOut

The Easing.SinInOut - smoothly accelerates the animation at the beginning, and smoothly decelerates the animation at the end.

For this demo I have also taken  Radial Gauge built with SkiaSharp.  ProgressBar from previous article control was updated a bit to draw 4 gradient colors:

barColorPaint.Shader = SKShader.CreateLinearGradient(
                               new SKPoint(skrect.Left, skrect.Top),
                               new SKPoint(skrect.Right, skrect.Bottom),
//two colore were added hereà new SKColor[] { EndColor.ToSKColor(), SKColors.Orange,
SKColors.Green, StartColor.ToSKColor() },
                               null,
                               SKShaderTileMode.Repeat);
 

Let’s take a look at our animation with easing function:

Xam Animation

Animation and colors are synchronized between Progress Bar and Radial Gauge.

As you can see with Xamarin.Forms we can easily create smooth, performant and cross-platform animation even with custom controls.

You can download the full sample source code here.

RELATED

24.01.2020.

Porting ios control to Xamarin.iOS and then to Xamarin.Forms (with SkiaSharp)

When we need to use some custom control from ios and use it in our Xamarin.ios application we have two options to do this. Make bindings or rewrite it with C#. You may wonder: “Why may I ever need to rewrite control instead of just making bindings?” The first and most obvious answer is “you need to extend this control with your own properties and functionality”. The second answers is “you will need it to port to other platforms”.

Read more