Animations are a great way to add polish to your user interface and make your app stand out. Xamarin.Forms includes its own animation infrastructure that allows for easy creation of simple animations, while also being versatile enough to create complex animations. The Xamarin.Forms animation classes target different properties of visual elements, with a typical animation progressively changing a property from one value to another over a period of time. Note that there is no XAML interface for the Xamarin.Forms animation classes. However, animations can be encapsulated in behaviors and then referenced from XAML.
In this blog post, I’m going to explore creating and cancelling animations using the ViewExtensions
class in Xamarin.Forms to create compelling animations that run on iOS, Android, and Windows.
Introduction to Animations
The ViewExtensions
class provides a number of extension methods that can be used to create simple animations that rotate, scale, translate, and fade VisualElement
instances. By default, each animation takes 250 milliseconds. However, a duration for each animation can be specified when creating the animation.
The extension methods provided by the ViewExtensions
class are TranslateTo
, ScaleTo
, RelScaleTo
, RotateTo
, RelRotateTo
, RotateXTo
, RotateYTo
, and FadeTo
. Each method is asynchronous and returns a Task<bool>
object. The return value is false
if the animation completes, and true
if the animation is cancelled. The animation methods should typically be used with the await
operator, which makes it possible to easily determine when an animation has completed. However, if there’s a requirement to let an animation complete in the background, then the await
operator can be omitted. In this scenario, the animation extension methods will quickly return after initiating the animation, with the animation occurring in the background.
The ViewExtensions
class also includes a CancelAnimations
method that can be used to cancel any animations.
Performing Simple Animations
Each extension method in the ViewExtensions
implements a single animation operation that progressively changes a property from one value to another value over a period of time.
Rotation
The following code example from the sample application demonstrates using the RotateTo
method to animate the Rotation
property of an Image
:
await image.RotateTo (360, 2000);
This code animates the Image
instance by rotating up to 360 degrees over 2 seconds (2000 milliseconds). The RotateTo
method obtains the current Rotation
property value for the start of the animation, and then rotates from that value to its first argument (360).
In addition, Xamarin.Forms supports relative rotation and rotation with anchors. For more information, see Relative Rotation and Scaling and Rotation with Anchors.
Scaling
The following code example from the sample application demonstrates using the ScaleTo
method to animate the Scale
property of an Image
:
await image.ScaleTo (2, 2000);
This code animates the Image
instance by scaling up to twice its size over 2 seconds (2000 milliseconds). The ScaleTo
method obtains the current Scale
property value (default value of 1) for the start of the animation, and then scales from that value to its first argument (2). This has the effect of expanding the size of the image to twice its size.
In addition, Xamarin.Forms supports relative scaling and scaling with anchors. For more information, see Relative Scaling and Scaling and Rotation with Anchors.
Translation
The following code example from the sample application demonstrates using the TranslateTo
method to animate the TranslationX
and TranslationY
properties of an Image
:
await image.TranslateTo (-100, -100, 1000);
This code animates the Image
instance by translating it horizontally and vertically over 1 second (1000 milliseconds). The TranslateTo
method simultaneously translates the image 100 pixels to the left, and 100 pixels upwards. This is because the first and second arguments are both negative numbers. Providing positive numbers would translate the image to the right, and down.
Fading
The following code example from the sample application demonstrates using the FadeTo
method to animate the Opacity
property of an Image
:
await image.FadeTo (1, 4000);
This code animates the Image
instance by fading it in over 4 seconds (4000 milliseconds). The FadeTo
method obtains the current Opacity
property value for the start of the animation, and then fades in from that value to its first argument (1).
Cancelling Animations
An application can cancel one or more animations with a call to the static ViewExtensions.CancelAnimations
method, as demonstrated in the following code example from the sample application:
ViewExtensions.CancelAnimations (image);
This will immediately cancel all animations that are currently running on the Image
instance.
Compound Animations
It’s also possible to create sequential animations with subsequent animation methods executing after the previous method has completed. These can be created with the await
operator, as demonstrated in the following code example from the sample application:
await image.TranslateTo (-100, 0, 1000);Â Â Â // Move image left await image.TranslateTo (-100, -100, 1000); // Move image up await image.TranslateTo (100, 100, 2000);Â Â // Move image diagonally down and right await image.TranslateTo (0, 100, 1000);Â Â Â Â // Move image left await image.TranslateTo (0, 0, 1000);Â Â Â Â Â Â // Move image up
In this example, the Image
is translated over 6 seconds (6000 milliseconds). The translation of the Image
uses five translation animations, with the await
operator indicating that each animation executes sequentially. Therefore, subsequent animation methods execute after the previous method has completed.
Composite Animations
Composite animations can be created by mixing awaited and non-awaited animations and using the Task.WhenAny
and Task.WhenAll
methods to run multiple asynchronous methods concurrently. Both methods return a Task
object and accept a collection of methods that each return a Task
object.
The following code example, from the sample application, demonstrates using the Task.WhenAll
method to run multiple asynchronous animation methods concurrently:
// 10 minute animation uint duration = 10 * 60 * 1000; await Task.WhenAll ( Â image.RotateTo (307 * 360, duration), Â image.RotateXTo (251 * 360, duration), Â image.RotateYTo (199 * 360, duration) );
In this example, the Task.WhenAll
method call contains three tasks, each of which executes over 10 minutes. Each Task
makes a different number of 360 degree rotations: 307 rotations for RotateTo
, 251 rotations for RotateXTo
, and 199 rotations for RotateYTo
. These values are prime numbers, therefore ensuring that the rotations aren’t synchronized and hence won’t result in repetitive patterns.
The following screenshots show the multiple rotations in progress on each platform:
Controlling Velocity Changes
The animation extension methods in the ViewExtensions
class allow an easing function to be specified as the final method parameter. The easing function, specified by the Easing
class, controls how an animation speeds up or slows down as it runs.
The following code example demonstrates specifying different easing functions in a compound animation:
await image.TranslateTo(0, 200, 2000, Easing.BounceIn); await image.ScaleTo(2, 2000, Easing.CubicIn); await image.RotateTo(360, 2000, Easing.SinInOut); await image.ScaleTo(1, 2000, Easing.CubicOut); await image.TranslateTo(0, -200, 2000, Easing.BounceOut);
By specifying an easing function for an animation, the animation velocity becomes non-linear and produces the effect provided by the easing function. For example, the BounceIn
easing function bounces the animation at the beginning, the CubicIn
easing function slowly accelerates the animation, and the SinInOut
easing function smoothly accelerates the animation at the beginning and smoothly decelerates the animation at the end.
Omitting an easing function when creating an animation causes the animation to use the default Linear
easing function, which produces a linear velocity.
In addition, custom easing functions can be created. For more information, see Custom Easing Functions.
Wrapping Up
The ViewExtensions
class provides extension methods that can be used to create simple animations that rotate, scale, translate, and fade VisualElement
instances. In addition, the ViewExtensions
class also includes a CancelAnimations
method that can be used to cancel any animations.
The animation extension methods in the ViewExtensions
class also allow an easing function to be specified as the final method parameter. The easing function, specified by the Easing
class, controls how an animation speeds up or slows down as it runs.
For more information, see Animation.
This was helpful, thanks 🙂