How to Add Animation in Xamarin.Forms
When we interact with mobile applications, we expect that the app feels alive. We hope to tap, swipe, drag, pinch every inch of the page and respond accordingly. This expectation is one of the many reasons why animation matters in mobile applications.
Back in the old days, with desktop and browser applications, the animation was complicated. It required manually moving objects pixel by pixel, and even if you could achieve animation, it was typically unwanted (remember those animated cursor trails that were common 15-20 years ago?)
But today, with mobile app development a priority, animation has reached the first-class status. It's become more natural in JavaScript, Android, and iOS development with plenty of libraries or built-in features.
App development with Xamarin.Forms is no different. Xamarin.Forms include animation infrastructure that's straightforward for creating simple animations, while also being versatile enough to create complex animations. In this article, we'll look at how you can use the animation API to customize your apps and look at a few controls' built-in animation features.
Animations in Xamarin.Forms
Xamarin provides API infrastructure for creating animations that can create both simple and complex animations across platforms. Basic animations give you the option to scale, rotate, fade, and translate (move along x or y) VisualElements in Xamarin.Forms. These animations let you quickly add animations to almost everything.
Using these animations is quite easy. To perform a scale animation for a Label, for instance, all one needs to do is use the ScaleTo method:
MyLabel.ScaleTo(2, 100);
In this case, the first argument is the scale (which will double here from 1), and the duration of the animation (100 milliseconds). Scaling the image back to the default size would be another call:
MyLabel.ScaleTo(1, 100);
Generally, the animations will progressively change a property from one value to another over a given duration. Animations are all asynchronous, cancellable, and task-based, and you can use the await operator to let one animation play out before starting a second.
Since you most likely would want to see both animations play out, you'd probably want to use await for both of these calls if they're back to back.
await MyLabel.ScaleTo(2, 100);
await MyLabel.ScaleTo(1, 100);
You also have the option to specify an Easing function for your animations. Easing functions dictate how the animation will play out over the duration. For example, a CubicInOut animation accelerates the animation at the beginning and decelerates at the end.
await MyLabel.ScaleTo(2, 100, Easing.CubicInOut);
await MyLabel.ScaleTo(1, 100, Easing.CubicInOut);
Xamarin has many functions predefined in the Easing class that covers common animation techniques, or you can create custom easing functions, if you prefer.
You can combine different types of animations to create composite animations. For example, we can combine the scaling animation above with a rotation of the label. In the code below we can play these animations together on a button click:
private async void Button_Clicked(object sender, EventArgs e)
{
MyLabel.RotateTo(360, 200, Easing.CubicInOut);
await MyLabel.ScaleTo(2, 100, Easing.CubicInOut);
await MyLabel.ScaleTo(1, 100, Easing.CubicInOut);
MyLabel.Rotation = 0;
}
As you can see in the above code, the scaling animations are awaited so that they play sequentially, whereas the rotation plays in the background and is not awaited.
Custom Shake Animation for Input Validation
We can take some of the animation principals discussed earlier and apply them to a more real-world use case, such as input validation. It's quite common to provide some animated feedback to a user when they enter disallowed or otherwise incorrect input. The shaking animation is a popular way of indicating these to your users. For this example, we'll use the C1AutoComplete control, but you could use any input control for the same effect.
For this example, we'll add a very simple layout with a Label and AutoComplete control:
<StackLayout Padding="20" x:Name="MyStack" Spacing="100">
<Label x:Name="MyLabel" FontSize="Large" Text="Enter an approved Country" HorizontalOptions="CenterAndExpand" Margin="0,0,0,20"/>
<c1:C1AutoComplete x:Name="MyAC" TextChanged="MyAC_TextChanged" AutoCompleteMode="StartsWith" DropDownMode="BelowOrAbove" DropDownBehavior="ButtonTap" DisplayMemberPath="Name"/>
</StackLayout>
You'll notice that there's a TextChanged event added into the XAML called MyAC_TextChanged. This event is where we'll implement both the validation and shake animation for the control.
First, let's look at the event and input validation:
private async void MyAC_TextChanged(object sender, C1.Xamarin.Forms.Input.TextChangedEventArgs e)
{
foreach (Country c in MyAC.ItemsSource)
{
//ToLower removes any check for case
if (c.Name.ToLower().StartsWith(MyAC.Text.ToLower()))
_flag = false;
}
if (_flag)
{
//Shake animation goes here
}
_flag = true;
}
All this code does is check that there's a potential match within the AutoComplete ItemsSource. As long as there is a possible match, it will keep the flag from being raised. If that isn’t a possibility, shake animation raises the flag.
The shake animation is easily implemented as a series of TranslateTo() calls:
uint timeout = 50;
ViewExtensions.CancelAnimation(MyAC);
await MyAC.TranslateTo(-15, 0, timeout);
await MyAC.TranslateTo(15, 0, timeout);
await MyAC.TranslateTo(-9, 0, timeout);
await MyAC.TranslateTo(9, 0, timeout);
await MyAC.TranslateTo(-5, 0, timeout);
await MyAC.TranslateTo(5, 0, timeout);
await MyAC.TranslateTo(-2, 0, timeout);
await MyAC.TranslateTo(2, 0, timeout);
MyAC.TranslationX = 0;
This moves the input control from side to side over a fixed interval, and you'll also notice that the values move closer to 0 to give it the impression that it's coming to rest. There is also a call to ViewExtensions.CancelAnimation() which cancels whatever previous animation hasn't finished executing. This call prevents the animations from continuing to run long after a user has stopped inputting characters.
Notice that we're also explicitly making sure TranslationX has been set back to 0 at the animation's conclusion.
Built-in Animation for ComponentOne Controls
Animations have always been an essential part of our Xamarin controls. When done right, animation helps bring your mobile apps to life. The best animations are typically subtle and practical. Most controls have built-in animation like FlexChart loading, FlexGrid column reordering, Gauges updating, and Input controls dropping down.
FlexChart Loading and Update Animation
FlexChart supports animation upon load, which is pretty standard. What's unique is the update animation that occurs when the underlying data collection changes by adding a value, removing a value, or modifying a value.
To see how it works, check out this update animation deep-dive.
FlexPie Loading, Update, and Selection Animation
Like FlexChart, FlexPie supports loading and update animation. It also supports selection animation, which allows the pie to spin like a game spinner.
For a coded example, try creating a pie chart with an interactive spinning selection.
FlexGrid Column Dragging
The column reordering/dragging feature for FlexGrid includes subtle animation. It's also effortless to code. If you've enabled dragging by setting the AllowDragging property, the columns and/or rows will smartly reposition (and animate) around the item you're dragging.
How Animations are Utilized in Today’s Applications
Animations are one of the most critical aspects of mobile controls, and now every control in our Xamarin suite comes with built-in animations that can easily be configured. To learn more about everything you can do with Xamarin, visit the Xamarin Month calendar. We're happy to receive feedback on any of our controls or features. Feel free to let us know how you feel about these built-in animation features in the comments below.