Introduction
Sometimes we can use small effects and animations to make the load process or heavy operations look more fluid and fast. This article shows how to add animations to our Xamarin and Xamarin.Forms (iOS, Android, and Windows Phone) apps.
There are two possible approaches to do this, the Xamarin way and the Xamarin.Forms approach. Let's start!
Xamarin.Forms
In Xamarin.Forms, every control you can use to build your user interface is based on the View class.
There are some extension methods for this class that allow you, using C# code, to create little animations for your controls. For example, you can create a simple page like this:
- public MainPage()
- {
- sampleLabel = new Label
- {
- Text = "Hello Xamarin.Forms animations!",
- TextColor = Color.Blue,
- XAlign = TextAlignment.Center,
- Opacity = 0
- };
-
- Content = new StackLayout
- {
- VerticalOptions = LayoutOptions.Center,
- Children =
- {
- sampleLabel
- }
- };
- }
By default, in the code above, the label opacity is set to 0, so it isn't displayed on the screen when the page is shown.
Next, you can override the OnAppearing method that is launched just before the page is showed. In this method you can animate the previously created label to make a FadeIn effect:
- protected override void OnAppearing()
- {
- base.OnAppearing();
-
- sampleLabel.FadeTo(1, 750, Easing.Linear);
- }
The FadeTo extension method receives the following three parameters:
- The final value of the property, in this case, Opacity.
- Animation duration in milliseconds.
- Easing function to use. In this case, a linear one, meaning a linear acceleration is added to the effect.
There are many more extension methods:
ScaleTo,
RotateTo,
LayoutTo, and
TranslateTo, all of them work the same way. You need to provide the final value and the duration, then you can provide an Easing function. You can take a detailed look at them
here.
There is also another method in the
ViewExtensions class, called
CancelAnimation, that get a View as a parameter and allows you to cancel an initiated animation on the target View.
You can also create combined animations, so you show more complex effects on the screen. All methods for animations are async, so you can play with await or not await them to make async or sync animations in an easy way:
- protected override async void OnAppearing()
- {
- base.OnAppearing();
-
- sampleLabel.FadeTo(1, 750, Easing.Linear);
-
- await sampleLabel.ScaleTo(2, 1500, Easing.CubicInOut);
- await sampleLabel.ScaleTo(1, 500, Easing.Linear);
- }
Here you can see some combined effects:
- FadeTo, with a duration of 750 milliseconds, without await.
- ScaleTo, with a duration of 1500 milliseconds, with await. This one is launched at the same time as the FadeTo, since it is not awaited.
- ScaleTo, with a duration of 500 milliseconds, with await. Since the previous ScaleTo is awaited, this one is launched when the previous one finished.
This way gives you a big control over how the animations are launched and allow you to combine many little animations to do awesome things.
Xamarin
Now we will see how to make the same animation in Xamarin. Since Xamarin asks you to create a native view for each platform, you will need to know how to make animations in iOS, Android, and Windows.
Windows
In Windows and Windows Phone you can use the power of XAML to create awesome animations. In the first place let's start creating the same Label, a TextBlock in XAML:
- <Grid>
- <TextBlock x:Name="TextHello"
- Text="{Binding Hello}"
- VerticalAlignment="Center"
- HorizontalAlignment="Center"
- Foreground="Blue"
- Opacity="0"
- RenderTransformOrigin=".5,.5">
- <TextBlock.RenderTransform>
- <CompositeTransform ScaleX="1" ScaleY="1"/>
- </TextBlock.RenderTransform>
- </TextBlock>
- </Grid>
In XAML you need to add a CompositeTransform instance to your element if you want to animate the scale or rotation of it. Now you can create a Storyboard to animate the Opacity and Scale of the TextBlock:
- <views:MvxWindowsPage.Resources>
- <Storyboard x:Key="TextBlockAnimation" Duration="0:0:1.5">
- <DoubleAnimationUsingKeyFrames Storyboard.TargetName="TextHello" Storyboard.TargetProperty="Opacity">
- <LinearDoubleKeyFrame KeyTime="0:0:0.750" Value="1"/>
- </DoubleAnimationUsingKeyFrames>
- <DoubleAnimationUsingKeyFrames Storyboard.TargetName="TextHello" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)">
- <LinearDoubleKeyFrame KeyTime="0:0:1.0" Value="2"/>
- <LinearDoubleKeyFrame KeyTime="0:0:1.5" Value="1"/>
- </DoubleAnimationUsingKeyFrames>
- <DoubleAnimationUsingKeyFrames Storyboard.TargetName="TextHello" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)">
- <LinearDoubleKeyFrame KeyTime="0:0:1.0" Value="2"/>
- <LinearDoubleKeyFrame KeyTime="0:0:1.5" Value="1"/>
- </DoubleAnimationUsingKeyFrames>
- </Storyboard>
- </views:MvxWindowsPage.Resources>
And finally you only need to launch the animation, using a behavior or by code in the OnNavigatedTo method:
- protected override void OnNavigatedTo(Windows.UI.Xaml.Navigation.NavigationEventArgs e)
- {
- base.OnNavigatedTo(e);
-
- var animation = (Storyboard)this.Resources["TextBlockAnimation"];
- animation.Begin();
- }
That's all, you have the same animation you made before in Xamarin.Forms, now in Windows and Windows Phone. Now is Android's turn.
Android
In Android you need to use AXML files to create the animation. Let's start creating the TextView to show in your page:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:local="http://schemas.android.com/apk/res-auto"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <TextView
- android:id="@+id/TextHello"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:textSize="40dp"
- android:textColor="#00F"
- local:MvxBind="Text Hello" />
- </LinearLayout>
Now it is time to start working with an animation set. Start creating a new AXML file in the Drawable folder inside the Resources folder. Call it TextAnimation, as in the following example:
- <?xml version="1.0" encoding="utf-8"?>
- <set xmlns:android="http://schemas.android.com/apk/res/android"
- android:shareInterpolator="false">
- <alpha android:interpolator="@android:anim/linear_interpolator"
- android:toAlpha="1"
- android:startOffset="0"
- android:duration="750"/>
- <scale android:interpolator="@android:anim/linear_interpolator"
- android:scaleGravity="center_vertical"
- android:toXScale="2"
- android:toYScale="2"
- android:pivotX="50%"
- android:pivotY="50%"
- android:startOffset="0"
- android:duration="1000"/>
- <scale android:interpolator="@android:anim/linear_interpolator"
- android:scaleGravity="center_vertical"
- android:toXScale="1"
- android:toYScale="1"
- android:pivotX="50%"
- android:pivotY="50%"
- android:startOffset="1000"
- android:duration="500"/>
- </set>
To execute multiple animations over one object in Android, you need to create a SET. It behaves in a way like the XAML Storyboards. Then you can use various AXML objects like Alpha, Scale and Rotate to animate the object. All the animations here are all launched together, so you need to use the StartOffset property if you want to make any of them launch after another. And voilá! our animation is done and working!
iOS
Last but not least, iOS. Since the iOS interface is created in C# you can take advantage of it to easily create awesome animations. As with the previous platforms, start creating the screen contents in the override ViewDidLoad method:
- public override void ViewDidLoad()
- {
- View = new UIView { BackgroundColor = UIColor.White };
- base.ViewDidLoad();
-
-
- if (RespondsToSelector(new Selector("edgesForExtendedLayout")))
- {
- EdgesForExtendedLayout = UIRectEdge.None;
- }
-
- var label = new UILabel(new CGRect(10, 100, 300, 60));
- label.Alpha = 0f;
- label.TextColor = UIColor.Blue;
- Add(label);
-
- var set = this.CreateBindingSet<FirstView, Core.ViewModels.FirstViewModel>();
- set.Bind(label).To(vm => vm.Hello);
- set.Apply();
- }
Now you can use the Animate method of the UIView class to define and create your animation as in the following:
- private void CreateLabelAnimation(UILabel label)
- {
- UIView.Animate(0.75, 0, UIViewAnimationOptions.CurveLinear,
- () =>
- {
- label.Alpha = 1f;
- }, null);
- UIView.Animate(1, 0, UIViewAnimationOptions.CurveLinear,
- () =>
- {
- label.Transform = CGAffineTransform.MakeScale(2f, 2f);
- }, null);
- UIView.Animate(0.5, 1, UIViewAnimationOptions.CurveLinear,
- () =>
- {
- label.Transform = CGAffineTransform.MakeScale(1f, 1f);
- }, null);
- }
Animate the method has the following five parameters:
- Animation duration, in seconds.
- Animation offset in seconds, before the start.
- Type of easing/transition function to use from UIViewAnimationOptions enum.
- An action (void method without parameters) to execute. Here is where you can use the element transformations to animate them.
- An action (void method without parameters) to execute when the animation has finished.
The animation code above is so simple, it is nearly self-explanatory. The first animation simply increases the Alpha to 1 at 750 milliseconds with a linear easing function.
For the scale, you can use the
MakeScale method of the
CGAffineTransform object to create a transform for the element.
Finally
To end, you can grab the source code for all these samples in my GitHub account
here. I hope this little article and sample code help you make awesome animations in your apps.